Reputation: 11085
During my experience before, the paintComponent(Graphics g) of a panel will run when I just initial it and I can make it to repaint by calling repaint() method. But my demo below doesn't work like my experience. What's wrong with it?
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class BackgroundTest {
public static void main(String[] args) {
BackgroundTest backgroundTest = new BackgroundTest();
try {
backgroundTest.createUI();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void createUI() throws IOException{
JFrame frame = new JFrame("Background Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(true);
JPanel mainPanel = new JPanel();
JLabel backgroundLabel = new JLabel(new ImageIcon("background.png"));
JPanel imagePanel = new ImagePanel();
imagePanel.setPreferredSize(new Dimension(626, 434)); // it's the size of house.png
JScrollPane scrollPane = new JScrollPane(imagePanel);
backgroundLabel.add(scrollPane,BorderLayout.CENTER);
mainPanel.add(backgroundLabel);
frame.add(mainPanel,BorderLayout.CENTER);
frame.getContentPane().add(backgroundLabel,BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
@SuppressWarnings("serial")
class ImagePanel extends JPanel {
protected void paintComponent(Graphics g) {
System.out.println("I'm not be run");
super.paintComponent(g);
BufferedImage image = null;
try {
image = ImageIO.read(new File("house.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
g.drawImage(image, 0, 0, null);
}
}
}
Upvotes: 0
Views: 352
Reputation: 109823
But my demo below doesn't work like my experience. What's wrong with it?
never to load, provide any FileIO inside paint
/paintComponent
, prepare this Object
as Local Variable, means code lines
BufferedImage image = null;
try {
image = ImageIO.read(new File("house.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Upvotes: 4
Reputation: 347334
JLabel
has no layout manager installed by default, meaning that anything your add to is never resized and therefore is never painted, Swing is smart that way
Try using something like...
backgroundLabel.setLayout(new BorderLayout());
Don't load your images within the paintComponent
method, paints may occur often and within quick succession to each other, anything that slows down the paint process will slow it down for everything
You should also avoid using setPreferredSize
and instead, let the component decided based on what it knows, for example
class ImagePanel extends JPanel {
private BufferedImage image = null;
public ImagePanel() {
try {
image = ImageIO.read(new File("house.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public Dimension getPreferredSize() {
return image == null ? super.getPreferredSize() : new Dimension(image.getWidth(), image.getHeight());
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image != null) {
g.drawImage(image, 0, 0, null);
}
}
}
Upvotes: 3