首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >EDT-swing问题

EDT-swing问题
EN

Stack Overflow用户
提问于 2013-03-01 10:05:35
回答 2查看 254关注 0票数 0

我有一个在EDT中执行的方法。大概是这样的:

代码语言:javascript
复制
myMethod()
{
  System.out.prinln(SwingUtilities.isEventDispatchThread());

  for (int i = 0; i < 10; i++)
  {
   Thread.sleep(3000);
   someJPanel.remove(otherJPanel);
  }
}

我期望发生的事情:十个JPanels将从它们的父级中一个接一个地移除,每次移除之间有三秒钟的暂停……

实际发生了什么:所有的东西都冻结了30秒,之后所有10个元素都被一次性删除了。

控制台中的行始终为true (SwingUtilities.isEventDispatchThread())。

既然我是在EDT中做这些的,为什么这些变化不是即时的呢?为什么它要等待方法首先到达它的结尾?

我应该如何修改我的代码,以实现删除之间的三秒延迟?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-03-01 10:10:57

Swing使用单个线程来调度事件和处理重绘请求。只要你阻塞这个线程,你就会停止EDT处理这些重绘请求,让UI看起来像是“停止”了。

取而代之的是,使用javax.swing.Timer之类的东西来插入延迟并执行操作。这将在EDT中执行操作,但将在后台线程中等待。

请通读The Event Dispatching Thread以了解详细信息...

使用计时器更新的示例

代码语言:javascript
复制
public class SlowDecline {

    public static void main(String[] args) {
        new SlowDecline();
    }
    private TestPane last;

    public SlowDecline() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                TestPane parent = new TestPane(Color.RED);
                TestPane tp = add(parent, Color.BLUE);
                tp = add(tp, Color.GREEN);
                tp = add(tp, Color.CYAN);
                tp = add(tp, Color.LIGHT_GRAY);
                tp = add(tp, Color.MAGENTA);
                tp = add(tp, Color.ORANGE);
                tp = add(tp, Color.PINK);

                last = tp;

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(parent);
                frame.setSize(200, 200);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

                Timer timer = new Timer(1000, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        if (last != null) {
                            Container parent = last.getParent();
                            if (parent != null) {
                                parent.remove(last);
                                parent.repaint();
                                if (parent instanceof TestPane) {
                                    last = (TestPane) parent;
                                }
                            } else {
                                last = null;
                            }
                        } else {
                            (((Timer)e.getSource())).stop();
                        }
                    }
                });
                timer.setRepeats(true);
                timer.setCoalesce(true);
                timer.start();
            }
        });
    }

    public TestPane add(TestPane parent, Color color) {

        TestPane child = new TestPane(color);
        parent.add(child);
        return child;
    }

    public class TestPane extends JPanel {

        public TestPane(Color background) {
            setLayout(new BorderLayout());
            setBorder(new EmptyBorder(10, 10, 10, 10));
            setBackground(background);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(50, 50);
        }
    }
}
票数 7
EN

Stack Overflow用户

发布于 2013-03-01 10:13:46

这是因为UI线程负责绘制屏幕以及处理事件。当您将UI线程置于休眠状态时,不会再发生绘制或事件处理。当线程恢复绘制时,所有面板都已被移除。

这个网址在how to handle threading with Swing上是相当全面的。

最好创建一个删除面板的Thread。

(未测试)

代码语言:javascript
复制
Thread t = new Thread() {
   @Override
   public void run() {  // override the run() for the running behaviors
     for (int i = 0; i < 10; i++)
     {
        Thread.sleep(3000);
        SwingUtilities.invokeLater(new Runnable() {
          public void run() {
           someJPanel.remove(...);
          });
     }
   }
};
t.start();  // call back run()
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15149242

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档