问题
In my Main
I want to create a JFrame
, then I want to create a BackgroundPanel
and I want to add this one in the JFrame
.
This is Main class:
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);
}
}
This is BackgroundPanel class:
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);
}
}
And the JFrame
is a normal JFrame
class.
When I execute it, there are no errors, simply it put out a normal JFrame
without background.
Help me Please!
@nIcEcOw I used the code in the first answear to print my image on a JPanel. But when I execute it, there's an error in output.
this the error:
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)
I'm confused about project's structure. I noticed that i can't put the package folder in bin directory; this creates a conflict in my ide. I dont understand how i can put the java files in src and the package folder in bin directory. My java files are in package folder..how I can do this?
I'm using NetBeans IDE 8.0
I red NetBean's image importing tutorial, and there also tips me to create another package to import images within. Now I the code is:
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);
}
}
I changed :
imageIcon = new ImageIcon(ImageIO.read(ImagePanel.class.getResource(
"/images/aeroplaneright.jpeg")));
in
imageIcon = new javax.swing.ImageIcon(getClass().getResource("/org/me/myimageapp/newpackage/aeroplaneright.jpg"));
@nIcEcOw you're my hero! :D Now all works fine. But just another thing:
now I'm using your ImagePanel class in a bigger project. I'm also using part of SwingTest code in the Main class of project to create a frame of a customized jframe class (FramePrincipale) with ImagePanel background. When I execute I'm obtaining a frame with my bakcground, but there aren't the other swing elements (labels,textfields..) that are part of my customized jframe. How can I fix this?
this is Principale class (main project class):
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 is a JFrame Form that is in the same project.
@nIcEcOw: Now it works! Thank You for all man! :-)
回答1:
Considering that the directory structure for the project looks like this:
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://stackoverflow.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);
}
}
OUTPUT:

In response to edit
As mentioned in the edit, that you using some Integrated Development Environment - IDE
, for creating the application. Since, every IDE
use to work in a bit different way. Please see, if this post, regarding how to add images to Java Project, helps you in that direction.
EDIT for NetBeans
- Create a Java Project
- Provide any Project Name. In my case I am using SwingTest, as shown in image
- Provide Package Name. In my case I am using swingtest, as shown in image
- Right-click Source Packages. New -> Java Package. Under New Java Package window, provide Package Name, in my case I am using images
- Copy the image from the File System and move back to NetBeans IDE, Right-click the images package so created and paste the image(inside NetBeans IDE)
- Create two classes by Right-clicking swingtest package, New -> Java Class, the contents of which are shown below
That is it, you are done now. Run the Project, and you be able to see the images. Do watch the use of 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);
}
}
Steps with Images

Here is the link to loyalperson.jpg
EDIT 2:
For adding a customized component, do this:
- Go to Tools -> Palette -> Swing/AWT Components
- Click on New Categroy. in New Palette Category window, provide New Category Name
- Click OK and Close the Palette Manager window
- Open ImagePanel in editor, now select Source View, now select Tools -> Add to Palette and select the Category just created by you.
- That I guess, will do. Now the component can be seen on the Palette window, under the Category chosen previously, which one can drag/drop on to the JFrame/JComponent.
回答2:
if extends JPanel why not Override paint method in JPanel and then play with graphics ex: g.drawImage(img, x, y, width, height, ImageObserver)?
来源:https://stackoverflow.com/questions/24807952/using-a-jpanel-extension-class-to-set-a-background