【问题标题】:How to make a thread not freeze you whole JFrame. JAVA如何使线程不会冻结整个 JFrame。 JAVA
【发布时间】:2013-05-23 04:59:26
【问题描述】:

嘿,我只需要回答一个问题... 如何使以下代码不冻结我的整个 JFrame?

                try {
                Thread.sleep(Integer.parseInt(delayField.getText()) * 1000);
                System.out.println("Hello!");
            } catch(InterruptedException ex) {
                Thread.currentThread().interrupt();
            }

【问题讨论】:

    标签: java swing jframe freeze


    【解决方案1】:

    使用不同的线程来执行此任务。如果您在主 UI 线程中执行此操作,那么它将冻结。例如,您可以执行以下操作

      new Thread() {
    
            @Override
            public void run() {
                try {
                    Thread.sleep(Integer.parseInt(delayField.getText()) * 1000);
                    System.out.println("Hello!");
                } catch (InterruptedException ex) {
                    Thread.currentThread().interrupt();
                }
    
            }
        }.start();
    

    更新

    在 Robin 和 Marko 的明智建议之后,我正在用更好的解决方案更新答案。

        ActionListener taskPerformer = new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                    System.out.println("Hello!");
    
            }
        };
        javax.swing.Timer t = new javax.swing.Timer(Integer.parseInt(delayField.getText()) * 1000, taskPerformer);
        t.setRepeats(false);
        t.start();
    

    【讨论】:

    • 由于JTextField#getText 不是线程安全的,您不应该从另一个线程调用该方法,然后是 EDT
    • @Robin,是的,在 postin 时没有考虑到这一点 :(... 可以使用同步方法来获取文本.. 会有任何副作用吗?
    • 我会在该线程之外检索文本,然后简单地将其传递到那里。只是为了延迟,我会完全放弃线程并按照 Marko Topolnik 的建议使用 Timer
    • 感谢@Robin 启发我.. 我正在根据您的建议更新答案
    【解决方案2】:

    每当您要在 GUI 代码中使用 Thread.sleep 时,请停下来想想 Swing Timer,它是适合这项工作的工具。延迟安排您需要执行的任务。

    为此使用另一个线程并不是最好的建议:它浪费了大量的系统资源(一个线程),除了等待之外什么都不做。

    【讨论】:

      【解决方案3】:

      这不是在 java 中使用线程的正确方法。你应该使用 swingutilities.invokelater

      swing utils invoke later

      【讨论】:

        【解决方案4】:

        您不想在 UI(或事件调度线程)线程上执行此操作。而是在一个单独的线程中。否则(如您所见),您将阻止 UI。

        在单独的线程上执行耗时的操作是一个好习惯,如果这些线程需要执行一些后续的 UI 操作(例如,在上面的 UI 中显示“Hello”),则使用 SwingUtilities.invokeLater() p>

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-02-03
          • 2015-10-23
          • 2012-02-11
          • 1970-01-01
          • 1970-01-01
          • 2020-01-03
          相关资源
          最近更新 更多