简体   繁体   English

为什么JPanel的paintComponent(Graphics g)无法运行?

[英]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. 在我之前的经验中,面板的paintComponent(Graphics g)将在我刚初始化时运行,并且可以通过调用repaint()方法使其重新绘制。 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);
        }
    }
}

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 永远不要加载,在paint / paintComponent内部提供任何FileIO,将此Object准备为局部变量,意味着代码行

BufferedImage image = null;
try {
    image = ImageIO.read(new File("house.png"));
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

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 JLabel默认情况下未安装布局管理器,这意味着您添加到的任何内容都不会调整大小,因此也不会被绘制,Swing那样聪明

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 不要在paintComponent方法中加载图像,绘制可能经常发生并且彼此之间快速连续,任何减慢绘制过程的速度都会使所有操作变慢

You should also avoid using setPreferredSize and instead, let the component decided based on what it knows, for example 您还应该避免使用setPreferredSize ,而是让组件根据其所知道的来决定,例如

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);
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM