0

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);
        }
    }
}
Eugene
  • 10,627
  • 5
  • 49
  • 67
  • You add `scrollPane` to `JLabel` it isn't correct. What do you try achive? – alex2410 Jun 26 '14 at 10:41
  • Hopefully this [answer](http://stackoverflow.com/a/11372350/1057230), might be able to help you :-) Just not related, but for extra information, this [answer](http://stackoverflow.com/a/9866659/1057230) :-) – nIcE cOw Jun 26 '14 at 10:59

2 Answers2

4

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();
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
3

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);
        }
    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366