java - 重绘未被调用

标签 java swing repaint paintcomponent event-dispatch-thread

您好,我已经用谷歌搜索了,但无法弄清楚为什么我的 paintComp 方法没有被调用

我有以下代码 包 com.vf.zepto.view;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

import javax.imageio.ImageIO;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import com.vf.zepto.view.interfaces.ProcessorPanel;

public class CountryDetailsPanel extends JPanel implements ProcessorPanel, Runnable {
    private GridBagConstraints c = new GridBagConstraints();
    private String countryName;
    private Properties prop = new Properties();
    private BufferedImage image;

    public CountryDetailsPanel() {
        try {
            prop.load(new FileInputStream("country.props"));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //this.setLayout(new GridBagLayout());

        c.gridx = 0;
        c.gridy = 0;
        c.fill = GridBagConstraints.BOTH;
        c.insets = new Insets(5, 5, 5, 5);

        this.setPreferredSize(new Dimension(200, 200));
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        try {
            if(countryName != null) {
                String asset = prop.getProperty(countryName+".flag");

                if(!asset.equals(null)) {
                    image = ImageIO.read(new File(asset));
                    g.drawImage(image, 0, 0, null);
                }
            }
        } 
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void updateDetails(Object o) {
        countryName = (String)o;
        SwingUtilities.invokeLater(this);
    }

    @Override
    public void run() {
        this.repaint();
    }
}

并且在调用 this.repaint() 时期望调用 paintComponent 方法,但是为了爱情和金钱,它不是。

曾试图强制它使用 EDT,以防这是问题所在,但事实并非如此。

有什么想法吗?

最佳答案

  • 永远不要调用 paintComponent() repaint() 方法合并所有更改组件的请求(屏幕刷新之间可能有多个重绘请求) .它将更新请求添加到 GUI 事件队列,以便更新将与其他 GUI 操作正确协调(Swing 和 AWT 不是线程安全的)。此更新请求在处理后调用 update(),后者调用 paint(),后者调用您的 paintComponent()

    /li>
  • 为什么会有这个:

    @Override
    public void run() {
        this.repaint();
       }
    

它似乎没有任何用处(创建一个新线程来重绘一次?更不用说线程不在 EDT 而是在 JPanel 上调用 repaint()实例(如果在外部进行了修改,您甚至不必担心)。但是,要启动修改 UI 组件的线程,请使用 SwingTimer/SwingWorkerSwingUtilities#invokeXXX( )

  • 这可能不相关,但在您的代码中我看到了这一点:

            if(!asset.equals(null)) {
                image = ImageIO.read(new File(asset));
                g.drawImage(image, 0, 0, null);
            }
    

不要使用 equals()null 值进行比较,因为这可能会抛出 NullPointerException,因为您正试图 引用一个空指针,例如这段代码抛出一个 NPE:

    String s=null;
    if(!s.equals(null)) {//throws NPE
        System.out.println("Here");//is never printed
    }
  • 另外,正如 mKorbel 所说(给他+1)不要在 paintComponent() 中执行长时间运行的任务 全局声明您的 Image,在构造函数中分配它,然后使用它在 paintComponent() 中。 F.i

宁愿做:

public class TestPanel extends JPanel {

private Image image;

public TestPanel() {
image = ImageIO.read(new File(asset));
}

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
                if(asset!=null) {
                    g.drawImage(image, 0, 0, null);
                }
    }
}

关于java - 重绘未被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12692171/

相关文章:

java - 使用什么 Swing 组件来显示带描述的照片

java swing - 如何一次重新绘制所有组件,以便用户不会注意到它们被一一填充?

java - 实现与 ActionListener 交互的方法?

java - 滚动到 JTable 中最后添加的行

Java - 重新绘制 JPanel 会出现错误

c# - 在整个循环完成之前,标签文本不会更新

java - 如何在Java代码中使用当前日期以及注册期间使用的生日用户来计算年龄?

java - 为什么 Java 需要一个方法参数来正确推导泛型?

java - mysql、结果集和listtt

java - 使用 IntelliJ IDEA 配置 Spring MVC