V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
codechaser
V2EX  ›  Java

为什么这个 MyJDialogTest 对话框会在延时 3 秒后才显示?

  •  
  •   codechaser · 2018-06-23 11:26:48 +08:00 · 1576 次点击
    这是一个创建于 2374 天前的主题,其中的信息可能已经有所发展或是发生改变。
    package Chapter10;
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    
    public class DialogTest extends JFrame {
    
        public DialogTest(){
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            setSize(400,300);
    
            JPanel panel = new JPanel();
    
            JButton button = new JButton("MyJDialog");
            button.addActionListener(e -> {
                new MyJDialog(DialogTest.this, "Test", false).setVisible(true);
    
                try{
                    Thread.sleep(3000);
                }catch (InterruptedException ex){
    
                }
    
                System.out.println("button's actionListener runs in thread: "+Thread.currentThread());
            });
            panel.add(button);
    
            add(panel);
    
            setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(DialogTest::new);
        }
    }
    
    class MyJDialog extends JDialog{
        public MyJDialog(JFrame parent, String title, boolean modality){
            super(parent,title,modality);
            setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
            add(new JLabel("<html><h1><i>Bob</i></h1><hr>By Liao Maosheng</html>"),BorderLayout.CENTER);
    
            System.out.println("JDialog runs in thread: "+Thread.currentThread());
            JButton ok = new JButton();
            ok.setText("OK");
            ok.addActionListener(e -> {
    //            setVisible(false);
                dispose();
            });
    
            add(ok,BorderLayout.SOUTH);
    
            setSize(200,200);
        }
    }
    

    这里我发现 MyJDialogTest 也是运行在事件派遣线程里,设置了 modality 为 false,那么这里 MyDialogTest.setVisible()好像是立马返回了的,然后立刻开始延时,导致事件派遣队列不能更新 MyJDialogTest,所以这里的 setVisible 应该是异步调用吧?同一个线程里也能异步调用吗?

    4 条回复    2018-06-23 13:53:43 +08:00
    kaneg
        1
    kaneg  
       2018-06-23 11:46:39 +08:00 via iPhone
    Java 的 UI 是在 EDT 单线程里运行的,sleep 把 EDT 给阻塞了 3 秒,自然后续的 UI 改动就是在 3 秒以后了
    verrickt
        2
    verrickt  
       2018-06-23 12:06:52 +08:00 via Android
    做 WPF 的无条件猜测下,DialogTest 的 ctor 在 UI 线程上跑,sleep 阻塞了 ui 线程,所以 delay3 秒。
    codechaser
        3
    codechaser  
    OP
       2018-06-23 13:52:42 +08:00
    @kaneg 你好!这个 setVisible 算不算异步呢?我看到 doc 里面有这一段话:
    ```
    public void setVisible(boolean b)
    Shows or hides this Dialog depending on the value of parameter b.
    Overrides:
    setVisible in class Window
    Parameters:
    b - if true, makes the Dialog visible, otherwise hides the Dialog. If the dialog and/or its owner are not yet displayable, both are made displayable. The dialog will be validated prior to being made visible. If false, hides the Dialog and then causes setVisible(true) to return if it is currently blocked.
    Notes for modal dialogs.

    setVisible(true): If the dialog is not already visible, this call will not return until the dialog is hidden by calling setVisible(false) or dispose.
    setVisible(false): Hides the dialog and then returns on setVisible(true) if it is currently blocked.
    It is OK to call this method from the event dispatching thread because the toolkit ensures that other events are not blocked while this method is blocked.
    See Also:
    Window.setVisible(boolean), Window.dispose(), Component.isDisplayable(), Component.validate(), isModal()
    ```
    codechaser
        4
    codechaser  
    OP
       2018-06-23 13:53:43 +08:00
    @verrickt 谢谢你!能抽空看一下我回复楼上的吗?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   970 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 22:54 · PVG 06:54 · LAX 14:54 · JFK 17:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.