【问题标题】:Java - How to set timeout for Event Dispatch thread?Java - 如何为事件调度线程设置超时?
【发布时间】:2018-04-29 05:30:02
【问题描述】:

我有一个 Java 应用程序,有些操作需要一些时间才能加载,所以我没有在操作完成时冻结程序,而是使用以下代码显示“请稍候...”对话框:

SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        pleaseWaitDialog.setVisible( true );
    }
});

有时正在执行的操作由于某种原因挂起,所以我想为这个“请稍候...”对话框设置一个超时时间,使其在 5 分钟后自动消失并显示错误消息。我该怎么做?

【问题讨论】:

    标签: java multithreading swing dialog timeout


    【解决方案1】:

    基本概念是使用单次运行 Swing Timer,当触发时,您可以处理对话框,例如...

    import java.awt.AWTEvent;
    import java.awt.Component;
    import java.awt.Dialog;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Frame;
    import java.awt.GraphicsConfiguration;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Toolkit;
    import java.awt.Window;
    import java.awt.event.AWTEventListener;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.beans.PropertyChangeEvent;
    import java.beans.PropertyChangeListener;
    import javax.swing.JButton;
    import javax.swing.JDialog;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    import javax.swing.Timer;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    TimeoutDialog dialog = new TimeoutDialog(5 * 60, (Window) null, "Testing");
                    dialog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                    dialog.add(new TestPane());
                    dialog.pack();
                    dialog.setLocationRelativeTo(null);
                    dialog.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            public TestPane() {
                setLayout(new GridBagLayout());
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.gridwidth = GridBagConstraints.REMAINDER;
                add(new JLabel("This is a bad idea"), gbc);
                add(new JButton("Don't tell me"), gbc);
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(200, 200);
            }
    
        }
    
        public class TimeoutDialog extends JDialog {
    
            private long timeOut = 90 * 1000;
            private long startTime;
            private Timer timer;
            private String originalTitle;
    
            public TimeoutDialog(long timeOut) {
                init(timeOut);
            }
    
            public TimeoutDialog(long timeOut, Frame owner) {
                super(owner);
                init(timeOut);
            }
    
            public TimeoutDialog(long timeOut, Frame owner, boolean modal) {
                super(owner, modal);
                init(timeOut);
            }
    
            public TimeoutDialog(long timeOut, Frame owner, String title) {
                super(owner, title);
                init(timeOut);
            }
    
            public TimeoutDialog(long timeOut, Frame owner, String title, boolean modal) {
                super(owner, title, modal);
                init(timeOut);
            }
    
            public TimeoutDialog(long timeOut, Frame owner, String title, boolean modal, GraphicsConfiguration gc) {
                super(owner, title, modal, gc);
                init(timeOut);
            }
    
            public TimeoutDialog(long timeOut, Dialog owner) {
                super(owner);
                init(timeOut);
            }
    
            public TimeoutDialog(long timeOut, Dialog owner, boolean modal) {
                super(owner, modal);
                init(timeOut);
            }
    
            public TimeoutDialog(long timeOut, Dialog owner, String title) {
                super(owner, title);
                init(timeOut);
            }
    
            public TimeoutDialog(long timeOut, Dialog owner, String title, boolean modal) {
                super(owner, title, modal);
                init(timeOut);
            }
    
            public TimeoutDialog(long timeOut, Dialog owner, String title, boolean modal, GraphicsConfiguration gc) {
                super(owner, title, modal, gc);
                init(timeOut);
            }
    
            public TimeoutDialog(long timeOut, Window owner) {
                super(owner);
                init(timeOut);
            }
    
            public TimeoutDialog(long timeOut, Window owner, ModalityType modalityType) {
                super(owner, modalityType);
                init(timeOut);
            }
    
            public TimeoutDialog(long timeOut, Window owner, String title) {
                super(owner, title);
                init(timeOut);
            }
    
            public TimeoutDialog(long timeOut, Window owner, String title, ModalityType modalityType) {
                super(owner, title, modalityType);
                init(timeOut);
            }
    
            public TimeoutDialog(long timeOut, Window owner, String title, ModalityType modalityType, GraphicsConfiguration gc) {
                super(owner, title, modalityType, gc);
                init(timeOut);
            }
    
            protected void init(double timeOutValue) {
    
                this.timeOut = Math.round(timeOutValue * 1000);
    
                timer = new Timer(1000, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        long runningTime = System.currentTimeMillis() - startTime;
                        System.out.println(runningTime + "/" + timeOut);
                        if (runningTime >= timeOut) {
                            timer.stop();
                            dispose();
                        } else {
                            String title = originalTitle + " [" + (((timeOut - runningTime) / 1000) + 1) + "]";
                            setTitle(title);
                        }
                    }
                });
    
                originalTitle = getTitle();
                String title = originalTitle + " [" + ((timeOut / 1000)) + "]";
                setTitle(title);
                addPropertyChangeListener("title", new PropertyChangeListener() {
                    @Override
                    public void propertyChange(PropertyChangeEvent evt) {
                        if (!timer.isRunning()) {
                            originalTitle = (String) evt.getNewValue();
                        }
                    }
                });
    
                addWindowListener(new WindowAdapter() {
                    @Override
                    public void windowOpened(WindowEvent e) {
                        timer.start();
                    }
    
                    @Override
                    public void windowClosed(WindowEvent e) {
                        timer.stop();
                    }
    
                });
            }
    
        }
    
    }
    

    另一个想法可能是使用某种观察者模式,其目的是向所有相关方发送定期“心跳”。

    您的长时间运行的进程会在它仍在工作时定期发出“心跳”/“脉冲”(以相对规律的间隔)。如果由于某种原因停止工作,相关方会知道,因为他们没有在规定的超时期限内收到脉冲,并且可以采取适当的行动 - 只是作为一个想法

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-23
      • 1970-01-01
      • 1970-01-01
      • 2011-05-06
      • 2018-09-04
      • 1970-01-01
      • 1970-01-01
      • 2013-01-02
      相关资源
      最近更新 更多