簡體   English   中英

為什么JPanel的paintComponent(Graphics g)無法運行?

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

在我之前的經驗中,面板的paintComponent(Graphics g)將在我剛初始化時運行,並且可以通過調用repaint()方法使其重新繪制。 但是我下面的演示並不像我的經驗那樣工作。 它出什么問題了?

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

但是我下面的演示並不像我的經驗那樣工作。 它出什么問題了?

永遠不要加載,在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默認情況下未安裝布局管理器,這意味着您添加到的任何內容都不會調整大小,因此也不會被繪制,Swing那樣聰明

嘗試使用類似...

backgroundLabel.setLayout(new BorderLayout());

不要在paintComponent方法中加載圖像,繪制可能經常發生並且彼此之間快速連續,任何減慢繪制過程的速度都會使所有操作變慢

您還應該避免使用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