Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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 SwingUtilities InvokeLater-什么被认为是不好的做法?_Java_Multithreading_Swing_Invokelater_Edt - Fatal编程技术网

Java SwingUtilities InvokeLater-什么被认为是不好的做法?

Java SwingUtilities InvokeLater-什么被认为是不好的做法?,java,multithreading,swing,invokelater,edt,Java,Multithreading,Swing,Invokelater,Edt,我有一个问题,关于使用SwingUtilities的invokeLater方法的正确做法是什么 因此,首先,我想确认我对它的理解是正确的 据我所知,对GUI的更改必须在EDT上完成,因为Swing组件不是线程安全的。invokeLater方法将Runnable作为参数,该Runnable中包含的任何内容都将在EDT上运行。因此,对Swing组件的任何调用都被放入一种队列中,在EDT上一次执行一个队列 有了这些,我的问题是:使用这个的好方法是什么?据我所知,至少有两种方法: 1) 在main方法中

我有一个问题,关于使用SwingUtilities的invokeLater方法的正确做法是什么

因此,首先,我想确认我对它的理解是正确的

据我所知,对GUI的更改必须在EDT上完成,因为Swing组件不是线程安全的。invokeLater方法将Runnable作为参数,该Runnable中包含的任何内容都将在EDT上运行。因此,对Swing组件的任何调用都被放入一种队列中,在EDT上一次执行一个队列

有了这些,我的问题是:使用这个的好方法是什么?据我所知,至少有两种方法:

1) 在
main
方法中,将所有代码(例如GUI创建、控制器创建,甚至模型创建(假设为MVC类型模式))放置在invokeLater方法调用的可运行文件中。当然,这是假设模型中任何长时间运行的任务都将由SwingWorker执行

2) 将GUI创建放在调用器中,但控制器创建和模型创建放在
main
方法中。然后,无论何时需要从控制器访问Swing组件,都可以在invokeLater方法中弹出所述代码,将其放置在EDT队列中

这两种做法中哪一种被认为是最佳做法,还是不良做法?如果这两个都不好,有什么更好的方法来解决这个问题呢

任何信息都将不胜感激


谢谢。

SwingWorker并不特别,它只是一些常见场景的包装。它将代表您调用invokeLater,因此实际上您所呈现的两个案例都只是同一事物的实例

只需确保遵守以下两条规则: 1.不要拖延EDT
2.在EDT上执行与Swing相关的代码这确实是一个有趣的问题,而公认的答案并没有完全响应它

您建议的两种方法都是可以接受的,并且都会很好地工作,但是我相信第一种方法比第二种方法更好(在EDT上完成所有任务,如果有一些长期运行的任务,则在SwingWorker上完成,如果与Swing无关,则在新线程上完成)


为什么?正如@ThomasKrägler所指出的:

虽然您可以在主线程和EDT之间拆分这些任务(模型、控制器和视图创建)(在UI首次显示之前可能会增加几毫秒),但这也会使应用程序的设计复杂化(多线程不是一个容易的主题),并使代码库中充斥着invokeLater()调用

考虑到EDT在初始化模型和控制器(从而启动视图)之前不需要处理任何内容。因此,您可以使用EDT来初始化它们,因为它不会对您的UI产生任何负面影响(目前还没有UI)


这样做,您将节省大量的
invokeLater
调用以及忘记调用
invokeLater
时可能出现的错误。您的代码看起来也会更干净。

谢谢!因此,当您在我的OP中说“EDT上的peform swing相关代码”时,例如,在案例1)中,视图、模型和控制器都在invokeLater中实例化,因此我假设它们都在EDT上。但是,该模型不在EDT上执行其代码,而是创建一个新的SwingWorker来执行长时间运行的任务。这种做法不好吗?@DBS:不。创建一个新的SwingWorker来完成长期运行的任务是正确的做法。@GilbertLeBlanc谢谢!因此,从我所看到的情况来看,使用它没有真正的“坏”方法,除非您正在做一些非常愚蠢的事情,比如运行与EDT上的Swing组件无关的代码,并最终导致GUI挂起。如果这是对JComponent的方法调用,那么您需要从EDT执行,否则,仅在EDT即时进行。模型、视图、控制器,可能只有EDT上的视图内容。