簡體   English   中英

不被重塗

[英]repaint not being called

嗨,我已經用谷歌搜索,無法弄清楚為什么我的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方法,但出於愛或金錢的考慮,它不是this.repaint()

試圖迫使它使用EDT,以防萬一,但這不是問題。

有任何想法嗎?

  1. 不要加載圖像或其他硬或長期運行的代碼paintComponent

  2. 將此Object作為局部變量加載一次

  3. paintComponent()被稱為

    • 隱式地,當JComponent需要重繪時,或

    • 明確地,例如,在每個鼠標事件上,如果要從MouseMotionListener調用paintComponent()

  4. 如果有動畫,則使用Swing Timer並調用repaint()

  • 您永遠不要調用paintComponent()repaint()方法合並所有更改組件的請求(在屏幕刷新之間可能有多個重新繪制請求)。 它將更新請求添加到GUI事件隊列,以便該更新將與其他GUI操作正確配合(Swing和AWT都不是線程安全的)。 處理此更新請求后,將調用update() ,后者將調用paint() ,后者將調用paintComponent()

  • 為什么要這樣:

     @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()使用它。 Fi

寧願:

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