Использование класса расширения 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);
}
}
ВЫХОД:
В ответ на редактирование
Как уже упоминалось в редактировании, что вы используете некоторые Integrated Development Environment - IDE
, для создания приложения. Так как каждый IDE
использовать для работы немного по-другому. Пожалуйста, посмотрите, поможет ли вам эта публикация в этой статье о том, как добавлять изображения в Java Project.
РЕДАКТИРОВАТЬ для NetBeans
- Создать проект Java
- Укажите любое имя проекта. В моем случае я использую SwingTest, как показано на рисунке
- Укажите имя пакета. В моем случае я использую swingtest, как показано на рисунке
- Щелкните правой кнопкой мыши Source Packages. Новый -> Пакет Java. Под окномNew Java Package укажите Имя пакета, в моем случае я использую изображения
- Скопируйте изображение из файловой системы и вернитесь в среду IDENetBeans. Щелкните правой кнопкой мыши созданный пакет изображений и вставьте изображение (в среде IDE NetBeans).
- Создайте два класса, щелкнув правой кнопкой мыши пакет 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);
}
}
Шаги с изображениями
Вот ссылка на loyalperson.jpg
РЕДАКТИРОВАТЬ 2:
Для добавления настроенного компонента сделайте это:
- Перейдите вИнструменты -> Палитра -> Компоненты Swing/AWT
- Нажмите на новую категорию. в окне New Palette Categoryукажите название новой категории
- Нажмите "ОК" и закройте окно "Диспетчер палитр".
- Откройте ImagePanel в редакторе, теперь выберите " Исходный вид", затем выберите " Инструменты" -> "Добавить в палитру" и выберите только что созданную вами категорию.
- Это, я думаю, сделаю. Теперь компонент можно увидеть в окне "Палитра" под ранее выбранной категорией, которую можно перетащить в JFrame/JComponent.
Если расширяет JPanel, почему бы не переопределить метод рисования в JPanel, а затем поиграть с графикой, например: g.drawImage(img, x, y, ширина, высота, ImageObserver)?