简体   繁体   English

不被重涂

[英]repaint not being called

Hi I have googled and can't figured out why my paintComp method isnt being called 嗨,我已经用谷歌搜索,无法弄清楚为什么我的paintComp方法没有被调用

I have the following code package com.vf.zepto.view; 我有以下代码包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();
    }
}

and when calling this.repaint() expect the paintComponent method to be called but for love nor money it isnt. 并在调用this.repaint()时会调用paintComponent方法,但出于爱或金钱的考虑,它不是this.repaint()

Have tried to force it to use the EDT incase that was the issue but its not. 试图迫使它使用EDT,以防万一,但这不是问题。

any ideas? 有任何想法吗?

  1. Do not load image or another hard or long running code in paintComponent 不要加载图像或其他硬或长期运行的代码paintComponent

  2. Load this Object as a local variable and only one time 将此Object作为局部变量加载一次

  3. paintComponent() is called paintComponent()被称为

    • implicitly, when JComponent requires repaint, or 隐式地,当JComponent需要重绘时,或

    • explicitly, for example on every of mouse event if one were to invoke paintComponent() from a MouseMotionListener . 明确地,例如,在每个鼠标事件上,如果要从MouseMotionListener调用paintComponent()

  4. If there is animation, then to use Swing Timer and call repaint() . 如果有动画,则使用Swing Timer并调用repaint()

  • You should never call paintComponent() the repaint() method consolidates all requests to change the component (there may be several repaint requests between screen refreshes). 您永远不要调用paintComponent()repaint()方法合并所有更改组件的请求(在屏幕刷新之间可能有多个重新绘制请求)。 It adds an update request to the GUI event queue so that the update will be properly coordinated with other GUI actions (Swing and AWT are not thread-safe). 它将更新请求添加到GUI事件队列,以便该更新将与其他GUI操作正确配合(Swing和AWT都不是线程安全的)。 This update request, when processed, calls update() , which calls paint() , which calls your paintComponent() 处理此更新请求后,将调用update() ,后者将调用paint() ,后者将调用paintComponent()

  • Why have this: 为什么要这样:

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

It does not seem of any use (creating a new thread to repaint once? Not to mention the thread is not on EDT rather call repaint() on the JPanel instance (if modified externally other than that you shouldnt even worry). However to start a thread which modifeis UI componets use s SwingTimer / SwingWorker or SwingUtilities#invokeXXX() 它似乎没有任何用处(创建一个新的线程来重新绘制一次?更不用说该线程不在EDT上,而是在JPanel实例上调用repaint() (如果在外部进行了修改,则您甚至不必担心)。修改UI组件的线程使用SwingTimer / SwingWorkerSwingUtilities#invokeXXX()

  • This might not be related but in your code I see this: 这可能不相关,但是在您的代码中我看到了:

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

dont use equals() to compare to a null value as this might throw a NullPointerException because you are attempting to deference a null pointer, for example this code throws a NPE : 不要使用equals()null值进行比较,因为这可能会引发NullPointerException因为您正尝试引用空指针,例如,此代码将引发NPE

    String s=null;
    if(!s.equals(null)) {//throws NPE
        System.out.println("Here");//is never printed
    }
  • Also as mKorbel has said (+1 to him) dont do long running tasks in paintComponent() declare your Image globally, assign it in the constructor and then use it in paintComponent() . 同样,正如mKorbel所说的(对他+1),不要在paintComponent()执行长时间运行的任务,而是全局声明您的Image ,在构造函数中分配它,然后在paintComponent()使用它。 Fi Fi

rather do: 宁愿:

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

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

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