如果在JFrame代码中调用了repaint(),则JPanel不会重绘 [英] JPanel doesn't repaint if repaint() is called within JFrame code

查看:149
本文介绍了如果在JFrame代码中调用了repaint(),则JPanel不会重绘的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类ForestCellularJPanel,该类扩展了JPanel并显示Forest.我写了一个原始代码来创建JFrameForestCellularJPanel并将CellularJPanel添加到JFrame.接下来是无限循环,该循环使Forest更新和CellularJPanel重新绘制.

I have a class Forest and CellularJPanel, which extends JPanel and displays Forest. I wrote a primitive code to create JFrame, Forest, CellularJPanel and add CellularJPanel to the JFrame. Next is an infinite loop, which makes Forest update and CellularJPanel repaint.

    JFrame jFrame = new JFrame();          

    Forest forest = new Forest();
    CellularJPanel forestJPanel = new CellularJPanel(forest);

    jFrame.add(forestJPanel);

    jFrame.pack();
    //jFrame.setResizable(false);
    jFrame.setLocationRelativeTo(null);
    jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    jFrame.setVisible(true);

    while (true)
    {
        try
        {
            forestJPanel.repaint();
            forest.update();
            forest.sleep(); // calls Thread.sleep(...)
        }   
        catch (InterruptedException e)
        {

        }
    }

这是CellularJPanel类的代码:

public class CellularJPanel extends JPanel
{
    private CellularAutomata cellularAutomata;

    public CellularJPanel(CellularAutomata cellularAutomata)
    {
        super();
        this.cellularAutomata = cellularAutomata;
        setPreferredSize(this.cellularAutomata.getDimension());
    }

    @Override
    public void paintComponent(Graphics g)     
    {
        super.paintComponent(g);            
        Graphics2D graphics2D = (Graphics2D)g;
        cellularAutomata.draw(graphics2D);
    }
}

如果我在main()方法中使用以上代码,则一切正常, CellularJPanel重新绘制,paintComponent()通常被调用.

If I use above code within main() method, then everything works fine, CellularJPanel repaints, paintComponent() is called normally.

如果我将相同的代码粘贴到UI JFrame按钮单击事件方法,则新的JFrame会显示甚至显示Forest的初始状态,因为一旦调用jFrame.setVisible(true)时就会调用paintComponent.然后,将执行 while循环,但是CellularJPanel不会重新绘制,不会调用paintComponent .我不知道为什么,也许我应该以某种方式使用SwingUtilities.invokeLater(...)java.awt.EventQueue.invokeLater,但是我已经尝试了它们,但是它没有用,我做错了.

If I paste the same code to UI JFrame button click event method, then new JFrame shows and even displays initial state of the Forest, because paintComponent is once called, when jFrame.setVisible(true) is called. Then while loop is being executed, but CellularJPanel doesn't repaint, paintComponent is not called. I have no idea why, maybe I should use SwingUtilities.invokeLater(...) or java.awt.EventQueue.invokeLater somehow, but I've tried them and it didn't work, I'm doing something wrong.

有什么建议吗?

P.S. 我的目标是在单击该按钮的同一UI JFrame中显示CellularJPanel.但是,即使我将此面板添加到主UI JFrame中,也无法正常工作.

P.S. My target is to display CellularJPanel within the same UI JFrame, from which button was clicked. But even if I add this panel to main UI JFrame, it doesn't work.

推荐答案

您的问题是

Your problem is having a while(true) on the Event Dispatch Thread which will block anything related to UI because UI events aren't getting handled anymore.

事件分发线程(单个线程)处理UI事件消息的队列,直到处理while(true)循环正在运行的线程为止.然后它会阻止任何进一步的处理,因为上面存在无限循环.从该循环中调用SwingUtilities.invokeLater将无济于事,因为它会将事件发布到事件分配线程中,该事件在while(true)循环中被阻止.

The event dispatch thread (a single thread) works down a queue of UI event messages, until it handles the one where your while(true) loop is running. It then blocks any further processing because there's an infinite loop on it. Calling SwingUtilities.invokeLater from that loop won't help because it posts an event to the event dispatch thread, which is blocked in the while(true) loop.

因此,请删除该循环,而应使用 为您的活动计时.在计时器事件中,更改UI的状态并调用repaint.计时器事件将与UI线程同步,因此允许更改UI组件的状态.

So remove that loop, instead use a javax.swing.Timer to time your events. In the timer event, change the state of your UI and call for a repaint. The timer event will be synchronized with the UI thread, so changing state of UI components is allowed.

这篇关于如果在JFrame代码中调用了repaint(),则JPanel不会重绘的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆