repaint() 不更新面板?

repaint() not updating panel?

我有一个class(不是public,所以你可能不知道class)正在用picture.draw(g2)画图。使用 picture.changeToDry() 我可以更改图片。当我调用图片并在实现的 paintComponent() 方法中更改它时,它工作正常。但是当我调用 changeToDry() 和 repaint() 之后,它不起作用。它只显示默认图片但不更新它。 我必须做什么,才能更改图片并以另一种方法更新 JPanel?它必须与 repaint() 相关,因为这些方法在 paintComponent() 中有效,但在其他地方无效。

编辑:update() 将在另一个 class 中调用。另外,正如我在评论中提到的,我无法提供有关 class 的更多信息,因为它是私人的,仅供教学 class。显然它应该有效。否则我的老师不会给我们的。 编辑 2:我有另一个正在绘制框架的 class ClimateFrame。我正在调用 update()

public class ClimatePanel extends JPanel {
    ClimatePicture picture = new ClimatePicture(100, 100);
    
    public void update() {
        picture.changeToDry();
        repaint(); // does not work
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        // picture.changeToDry() would work here
        picture.draw(g2);   
    }
}




public class ClimateFrame extends JFrame {
    
    public ClimateFrame() {
        setTitle("A task");
        setLayout(new BorderLayout());
        add(new ClimatePanel(), BorderLayout.CENTER);
    }
    
    public static void main(String [] args) {
        
        ClimateFrame frame = new ClimateFrame ();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800, 600);
        frame.setVisible(true);
        ClimatePanel climatePanel = new ClimatePanel();
        climatePanel.update();
        
        
    }
}

你的问题是:

public class ClimateFrame extends JFrame {
    
    public ClimateFrame() {
        setTitle("A task");
        setLayout(new BorderLayout());
        add(new ClimatePanel(), BorderLayout.CENTER);
    }
    
    public static void main(String [] args) {        
        ClimateFrame frame = new ClimateFrame ();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800, 600);
        frame.setVisible(true);
        ClimatePanel climatePanel = new ClimatePanel(); // ****** here ****
        climatePanel.update();
    }
}

您正在指定行创建一个新的 ClimatePanel 实例并更改其状态,而不是最初创建和显示的单独实例的状态。这与我在上面的评论中做出的猜测之一一致:

Right now we can guess:

  • it could be a Swing threading issue,
  • or you could be updating the wrong instance (THIS ONE)

解决方案:不要创建新的 ClimatePanel 实例,而是创建一个 ClimatePanel 字段,给它一个 ClimatePanel 引用,将它添加到 GUI,然后更新它的状态,现在是显示实例的状态。

例如,

public class ClimateFrame extends JFrame {
    private ClimatePanel climatePanel = new ClimatePanel(); // ADD
    
    public ClimateFrame() {
        setTitle("A task");
        setLayout(new BorderLayout());
        // add(new ClimatePanel(), BorderLayout.CENTER); // REMOVE
        add(climatePanel, BorderLayout.CENTER); // ADD    
    }
    
    // allow visibility of the climate panel method
    public void updateClimatePanel() {
        climatePanel.update();
    }
    
    public static void main(String [] args) {        
        ClimateFrame frame = new ClimateFrame ();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800, 600);
        frame.setVisible(true);
        // ClimatePanel climatePanel = new ClimatePanel(); // REMOVE
        frame.updateClimatePanel();
    }
}