Использование класса расширения 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 в классе Main проекта для создания рамки настраиваемого класса jframe (FramePrincipale) с фоном ImagePanel. Когда я выполняю, я получаю кадр с моим bakcground, но нет других элементов свинга (метки, текстовые поля...), которые являются частью моего настраиваемого 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: Теперь это работает! Спасибо всем за человека!:-)

2 ответа

Решение

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

 Since Images are Application Resources,
 it's 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
 https://stackru.com/a/9866659/1057230
 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.

РЕДАКТИРОВАТЬ для NetBeans

  1. Создать проект Java
  2. Укажите любое имя проекта. В моем случае я использую SwingTest, как показано на рисунке
  3. Укажите имя пакета. В моем случае я использую swingtest, как показано на рисунке
  4. Щелкните правой кнопкой мыши Source Packages. Новый -> Пакет Java. Под окномNew Java Package укажите Имя пакета, в моем случае я использую изображения
  5. Скопируйте изображение из файловой системы и вернитесь в среду IDENetBeans. Щелкните правой кнопкой мыши созданный пакет изображений и вставьте изображение (в среде IDE NetBeans).
  6. Создайте два класса, щелкнув правой кнопкой мыши пакет swingtest,New -> Java Class, содержимое которого показано ниже.

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

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:

Для добавления настроенного компонента сделайте это:

  1. Перейдите вИнструменты -> Палитра -> Компоненты Swing/AWT
  2. Нажмите на новую категорию. в окне New Palette Categoryукажите название новой категории
  3. Нажмите "ОК" и закройте окно "Диспетчер палитр".
  4. Откройте ImagePanel в редакторе, теперь выберите " Исходный вид", затем выберите " Инструменты" -> "Добавить в палитру" и выберите только что созданную вами категорию.
  5. Это, я думаю, сделаю. Теперь компонент можно увидеть в окне "Палитра" под ранее выбранной категорией, которую можно перетащить в JFrame/JComponent.

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

Другие вопросы по тегам