Eugene
Eugene

Reputation: 11085

Why doesn't paintComponent(Graphics g) of JPanel run?

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

Answers (2)

mKorbel
mKorbel

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

MadProgrammer
MadProgrammer

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

Related Questions