Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Swing-在EDT上运行_Java_Swing_Event Dispatch Thread - Fatal编程技术网

Java Swing-在EDT上运行

Java Swing-在EDT上运行,java,swing,event-dispatch-thread,Java,Swing,Event Dispatch Thread,关于Swing和使用EDT进行GUI更新,我有几个问题。我刚开始阅读这些东西,所以我是这方面的完全初学者: 需要在EDT上运行哪些操作?如果没有,是否只是提出了一个例外 是否有任何特定的时间,我们实际上是在EDT自动 如果我们使用SwingUtilities.invokeLater调度一个任务,我们将其排入GUI更新任务的当前队列(EDT),对吗 我猜对上面队列的访问是同步的,或者使用了一些并发集合,但是如果我从两个后台线程调度两个GUI更新任务,就不可能说首先添加哪一个?例如,如果线程1首先提

关于Swing和使用EDT进行GUI更新,我有几个问题。我刚开始阅读这些东西,所以我是这方面的完全初学者:

  • 需要在EDT上运行哪些操作?如果没有,是否只是提出了一个例外
  • 是否有任何特定的时间,我们实际上是在EDT自动
  • 如果我们使用
    SwingUtilities.invokeLater
    调度一个任务,我们将其排入GUI更新任务的当前队列(EDT),对吗
  • 我猜对上面队列的访问是同步的,或者使用了一些并发集合,但是如果我从两个后台线程调度两个GUI更新任务,就不可能说首先添加哪一个?例如,如果线程1首先提交一个任务,将一个JLable的文本设置为“是”,然后在很短的时间后,第二个线程出现并提交将该值设置为“否”的任务,那么我们是否可以保证结果为“是”,或者仅仅是操作系统如何安排这些事情的问题
  • SwingWorker如何确保在EDT上运行
    done()
    方法?它设置以下代码:

      future = new FutureTask<T>(callable) {
                   @Override
                   protected void done() {
                       doneEDT();
                       setState(StateValue.DONE);
                   }
               };
    
    future=newfuturetask(可调用){
    @凌驾
    受保护的void done(){
    不需要();
    设置状态(StateValue.DONE);
    }
    };
    
  • 所以我想知道FutureTask是否以某种方式确保调用了
    invokeLater


    感谢您的回答。

    1.在Java GUI应用程序中,
    main()
    方法的寿命不长,在调度事件调度程序线程中的GUI构造后,
    main()
    方法退出…现在它的EDT负责处理GUI。

    2.因此我们不需要在EDT上启动应用程序,它会自动完成。

    3始终在UI线程上保留UI工作,在非UI线程上保留非UI工作

    因此,始终保持您的EDT线程,这是仅用于GUI工作的GUI线程

    例如:

    4.创建一个单独的非UI线程来处理这个耗时的方法

    5.您可以简单地使用
    线程
    或使用专门引入Java的
    SwingWorker
    来同步UI和非UI线程

    6.SwingWorker不确保在EDT上运行done()方法,而是将其输出同步到EDT线程,即GUI线程

  • 基本上,每次使用Swing组件或Swing组件的模型时,都必须在EDT中完成。如果您不这样做,将不会提出任何例外。它可以工作,但也可能无法工作、行为不稳定、数据损坏等
  • 在EDT中调用每个Swing事件侦听器。基本上,除了main方法之外,Swing应用程序的每一行代码都默认在EDT中执行,除非您明确地启动线程、使用SwingWorker或类似的东西
  • 提交给SwingUtilities.invokeLater()的任务的执行顺序与提交的顺序相同
  • 在内部,它使用SwingUtilities.invokeLater()或类似的方法。未来任务与Swing无关。SwingWorker负责确保其done方法在EDT中执行。
    doneEDT()
  • 一个好的规则是所有操作(访问/更新/…)都应该在EDT上进行。javadoc中提到了一些例外(某些类的某些方法),但它们很难记住,因此更容易坚持“在EDT上做所有事情”的方法。不会引发异常(幸运的是,JavaFX修复了这个缺点)。您可以使用自定义的
    repaitmanager
    来检测大多数违规行为:请参阅
  • 由用户触发的所有事件都在EDT上处理。例如,如果用户单击按钮,相应的
    操作
    操作侦听器
    操作执行
    将在EDT上调用
  • 正确的
  • 你先安排的事情会先执行。调用
    invokeLater
    只需在队列末尾添加
    Runnable
    。稍晚再使用
    invokeLater
    将在先前计划的
    Runnable
    之后添加此新的
    Runnable
  • 查看
    doneEDT

    private void doneEDT() {
        Runnable doDone = 
            new Runnable() {
                public void run() {
                    done();
                }
            };
        if (SwingUtilities.isEventDispatchThread()) {
            doDone.run();
        } else {
            doSubmit.add(doDone);
        }
    }
    

  • SwingWorker通过以下代码确保在EDT上运行done()方法:

        Runnable doDone =
            new Runnable() {
                public void run() {
                    done();
                }
            };
        if (SwingUtilities.isEventDispatchThread()) {
            doDone.run();
        } else {
            doSubmit.add(doDone);
        }
    
    实际上,它将doDone变量添加到累加器unnable doSubmit中

    查看AccumerativeRunnable.java的源代码,您会发现下面有一段代码

    受保护的无效提交(){

    SwingUtilities.invokeLater(this)

    }


    这就是为什么swingworker确保方法done()在EDT上运行的原因。第6点:请参阅swingworker的javadoc类:事件调度线程:所有与Swing相关的活动都发生在该线程上。SwingWorker调用process和done()方法并通知此线程上的所有PropertyChangeListeners。所以它是第一个执行调用的线程,对吗?所以,有可能是操作系统会先安排第二个后台线程调用器调用,然后顺序就会混乱?5.我仍然不明白这是如何实现EDT的。do Submit将Runnable添加到AccumerativeRunnable…@Bober02请参阅javax.swing.SwingWorker.DoSubmitAccumulativeRunnable,由于使用swing
    计时器,它在EDT上执行。对于4:是的,您必须确保一个后台线程在另一个线程调度其可运行线程之前调度可运行线程。如果您希望控制订单,那么在某个时候,提交给doSubmit()的所有内容都在EDT中运行。你不必在意
    
        Runnable doDone =
            new Runnable() {
                public void run() {
                    done();
                }
            };
        if (SwingUtilities.isEventDispatchThread()) {
            doDone.run();
        } else {
            doSubmit.add(doDone);
        }