Использование класса расширения JPanel для установки фона

В моем Main я хочу создать JFrame, тогда я хочу создать BackgroundPanel, и я хочу добавить его в JFrame.

Это Основной класс:

public class Main {

    public static void main(String args[]) {
        Frame frame = new Frame();
        BackgroundPanel back = new BackgroundPanel();
        frame.getContentPane().add(back);
        frame.setSize(400, 287);
        frame.setVisible(true);
    }
}

Это BackgroundPanel класс:

import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class BackgroundPanel extends JPanel {

    private Image img;

    public BackgroundPanel() {
        img = Toolkit.getDefaultToolkit().createImage(getClass().getResource("sfondo.png"));
        loadImage(img);
    }

    private void loadImage(Image img) {
        try {
            MediaTracker track = new MediaTracker(this);
            track.addImage(img, 0);
            track.waitForID(0);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        setOpaque(false);
        g.drawImage(img, 0, 0, null);
    }
}

И JFrame является обычным классом JFrame.

Когда я выполняю его, ошибок нет, просто он выдает обычный JFrame без фона. Помогите мне, пожалуйста!

@nIcEcOw Я использовал код в первом ответе, чтобы напечатать свое изображение на JPanel. Но когда я его выполняю, появляется ошибка в выходе.

это ошибка:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: input == null!
    at javax.imageio.ImageIO.read(ImageIO.java:1388)
    at paintingexample.CustomPanel.<init>(PaintingExample.java:82)
    at paintingexample.PaintingExample.displayGUI(PaintingExample.java:28)
    at paintingexample.PaintingExample.access$000(PaintingExample.java:19)
    at paintingexample.PaintingExample$1.run(PaintingExample.java:42)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:312)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
    at java.awt.EventQueue.access$200(EventQueue.java:103)
    at java.awt.EventQueue$3.run(EventQueue.java:694)
    at java.awt.EventQueue$3.run(EventQueue.java:692)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
BUILD SUCCESSFUL (total time: 1 second)

Я запутался в структуре проекта. Я заметил, что я не могу поместить папку пакета в каталог bin; это создает конфликт в моей идее. Я не понимаю, как я могу поместить java файлы в src и папку пакета в каталог bin. Мои файлы java находятся в папке пакета. Как я могу это сделать?

Я использую NetBeans IDE 8.0

Я красноватый учебник по импортированию образа NetBean, а также подсказывает, как создать другой пакет для импорта изображений внутри. Теперь я код:

import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;

public class PaintingExample {

    private ImagePanel imagePanel;

    public void displayGUI() {
        JFrame frame = new JFrame("Swing Worker Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel contentPane = new JPanel();
        imagePanel = new ImagePanel();      
        contentPane.add(imagePanel);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                new PaintingExample().displayGUI();
            }
        };
        EventQueue.invokeLater(runnable);
    }
}


class ImagePanel extends JPanel {

    private ImageIcon imageIcon;

    public ImagePanel() {
        imageIcon = new javax.swing.ImageIcon(getClass().getResource("/org/me/myimageapp/newpackage/Schema elettrico divella rev 2014-Model.jpg"));
    }

    @Override
    public Dimension getPreferredSize() {
        return (imageIcon == null ? new Dimension(100, 100): new Dimension(
                                                   imageIcon.getIconWidth(), imageIcon.getIconHeight()));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(imageIcon.getImage(), 0, 0, this);
    }
}

Я изменил:

imageIcon = new ImageIcon(ImageIO.read(ImagePanel.class.getResource(
                                                    "/images/aeroplaneright.jpeg")));

в

imageIcon = new javax.swing.ImageIcon(getClass().getResource("/org/me/myimageapp/newpackage/aeroplaneright.jpg"));

@nIcEcOw ты мой герой!: D Теперь все работает нормально. Но совсем другое:

теперь я использую ваш класс ImagePanel в более крупном проекте. Я также использую часть кода SwingTest в основном классе проекта, чтобы создать кадр настраиваемого класса jframe (FramePrincipale) с фоном ImagePanel. Когда я выполняю, я получаю фрейм с моим bakcground, но нет других элементов swing (ярлыки, текстовые поля...), которые являются частью моего настраиваемого jframe. Как я могу это исправить?

это класс Principale (основной класс проекта):

import java.awt.EventQueue;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JPanel;


public class Principale {


    private ImagePanel imagePanel;
    private static FramePrincipale frame = new FramePrincipale();

    private void displayGUI() throws IOException {





        JPanel contentPane = new JPanel();
        imagePanel = new ImagePanel();      
        contentPane.add(imagePanel);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }



    public static void main(String[] args) {



        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    new Principale().displayGUI();
                } catch (IOException ex) {
                    Logger.getLogger(Principale.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        };
        EventQueue.invokeLater(runnable);

  while (true) {


      frame.scriviLabel();


    }     

    }

}

FramePrincipale - это форма JFrame, которая находится в одном проекте.

@nIcEcOw: Теперь это работает! Спасибо всем за человека!: -)

Ответы

Ответ 1

Учитывая, что структура каталогов для проекта выглядит так:

 Since Images are Application Resources,
 it always best to access them in the
 form of a URL, instead of File, as you are doing.
 Uncomment this below line and watch this answer
 of mine, as to HOW TO ADD IMAGES TO THE PROJECT
 /questions/10109/loading-image-resource/68101#68101
 In order to access images with getClass().getResource(path)
 here your Directory structure has to be like this
                 Project
                    |
         ------------------------
         |                      |
        bin                    src
         |                      |
     ---------             .java files             
     |       |                   
  package   images(folder)
  ( or              |
   .class        404error.jpg
   files, if
   no package
   exists.)

PaintingExample

import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;

public class PaintingExample {

    private ImagePanel imagePanel;

    private void displayGUI() {
        JFrame frame = new JFrame("Swing Worker Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel contentPane = new JPanel();
        imagePanel = new ImagePanel();      
        contentPane.add(imagePanel);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                new PaintingExample().displayGUI();
            }
        };
        EventQueue.invokeLater(runnable);
    }
}

class ImagePanel extends JPanel {

    private ImageIcon imageIcon;

    public ImagePanel() {
        try {
            imageIcon = new ImageIcon(ImageIO.read(ImagePanel.class.getResource(
                                                    "/images/aeroplaneright.jpeg")));
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return (imageIcon == null ? new Dimension(100, 100): new Dimension(
                                                   imageIcon.getIconWidth(), imageIcon.getIconHeight()));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(imageIcon.getImage(), 0, 0, this);
    }
}

ВЫВОД:

PAINTINGEXAMPLE

В ответ на редактирование

Как упоминалось в редакции, вы используете некоторые Integrated Development Environment - IDE для создания приложения. Поскольку каждый IDE используется для работы по-другому. Посмотрите, если этот пост, касающийся добавления изображений в Java Project, поможет вам в этом направлении.

EDIT для NetBeans

  • Создать проект Java
  • Укажите любое Название проекта. В моем случае я использую SwingTest, так как показано на фотографии
  • Предоставить Имя пакета. В моем случае я использую swingtest, так как показано на фотографии
  • Щелкните правой кнопкой мыши Исходные пакеты. Новый → Пакет Java. Под Новый пакет Java, укажите Имя пакета, в моем случае я использую изображения
  • Скопируйте изображение из Файловой системы и вернитесь к NetBeans. Щелкните правой кнопкой мыши созданный таким образом образ пакет и вставьте его (внутри среды IDE NetBeans).
  • Создайте два класса, щелкнув правой кнопкой мыши swingtest, Новый → Класс Java, содержимое которого показано ниже

Вот и все, теперь все готово. Запустите проект, и вы сможете видеть изображения. Наблюдайте за использованием getClass().getResource(...) thingy:

imageIcon = new ImageIcon(ImageIO.read(ImagePanel.class.getResource(
                                                    "/images/loyalperson.jpg")));

SwingTest

package swingtest;

import java.awt.*;
import javax.swing.*;

public class SwingTest {

    private ImagePanel imagePanel;

    private void displayGUI() {
        JFrame frame = new JFrame("Swing Worker Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel contentPane = new JPanel();
        imagePanel = new ImagePanel();      
        contentPane.add(imagePanel);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                new SwingTest().displayGUI();
            }
        };
        EventQueue.invokeLater(runnable);
    }
}

ImagePanel

package swingtest;

import java.awt.Dimension;
import java.awt.Graphics;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JPanel;

public class ImagePanel extends JPanel {

    private ImageIcon imageIcon;

    public ImagePanel() {
        try {
            imageIcon = new ImageIcon(ImageIO.read(
                         ImagePanel.class.getResource("/images/loyalperson.jpg")));
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return (imageIcon == null ? new Dimension(100, 100): new Dimension(
                         imageIcon.getIconWidth(),imageIcon.getIconHeight()));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(imageIcon.getImage(), 0, 0, this);
    }
}

Шаги с изображениями

ProjectImages

Вот ссылка на loyalperson.jpg

ИЗМЕНИТЬ 2:

Для добавления настраиваемого компонента выполните следующее:

  • Перейдите в Инструменты → Палитра → Компоненты Swing/AWT
  • Нажмите Новый Categroy. в окне Новая палитра, укажите Новое название категории
  • Нажмите ОК и закройте окно Диспетчер палитр
  • Откройте ImagePanel в редакторе, теперь выберите Исходный просмотр, теперь выберите Инструменты → Добавить в палитру и выберите Категория. созданный вами.
  • То, что я думаю, будет делать. Теперь компонент можно увидеть на Палитра в разделе Категория, выбранном ранее, который можно перетащить/переместить в JFrame/JComponent.

Ответ 2

если расширяет JPanel, почему бы не переопределить метод рисования в JPanel, а затем играть с графикой ex: g.drawImage(img, x, y, ширина, высота, ImageObserver)?