简体   繁体   English

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

[英]SwingUtilities InvokeLater- what is considered bad practice?

I've got a question about what would be the correct practice to use the invokeLater method of SwingUtilities.我有一个关于使用 SwingUtilities 的 invokeLater 方法的正确做法的问题。

So to begin, I'd like to confirm that I am understanding it correctly.所以首先,我想确认我理解正确。

From what I understand, changes to the GUI must be done on the EDT, because Swing components aren't thread safe.据我了解,必须在 EDT 上更改 GUI,因为 Swing 组件不是线程安全的。 The invokeLater method takes a Runnable as an argument, and anything contained in that runnable will be run on the EDT. invokeLater 方法将 Runnable 作为参数,并且该 runnable 中包含的任何内容都将在 EDT 上运行。 Therefore any calls made to Swing components are put in a kind of queue, which are executed one at a time on the EDT.因此,对 Swing 组件的任何调用都被放入一种队列中,在 EDT 上一次执行一个。

With that out of the way, my question then is: what is good practice for using this?有了这个,我的问题是:使用它的好习惯是什么? From what I can see there are at least two ways to do it:据我所知,至少有两种方法可以做到:

1) In the main method, place all code, such as GUI creation, Controller creation, and even the Model creation (assuming a MVC type pattern), in a Runnable that is invoked by the invokeLater method. 1) 在main方法中,将所有代码,例如 GUI 创建、Controller 创建,甚至 Model 创建(假设为 MVC 类型模式)放在由 invokeLater 方法调用的 Runnable 中。 Of course, this is assuming that any long running tasks in the Model would be executed with a SwingWorker.当然,这是假设 Model 中的任何长时间运行的任务都将使用 SwingWorker 执行。

2) Place GUI creation in a invokeLater, but Controller creation and Model creation in the main method. 2)将GUI创建放在invokeLater中,但Controller创建和Model创建在main方法中。 Then whenever you need to access a Swing component from a Controller, you pop said code in an invokeLater method to place it on the EDT queue.然后,每当您需要从 Controller 访问 Swing 组件时,您可以在 invokeLater 方法中弹出所述代码以将其放置在 EDT 队列中。

What one of these two would be considered best practice, or bad practice?这两个中的哪一个被认为是最佳实践或坏实践? And if neither of these two are good, what would be the better way to go about this?如果这两个都不好,那么 go 的更好方法是什么?

Any info would be hugely appreciated.任何信息将不胜感激。

Thanks.谢谢。

SwingWorker isn't special, it's just some wrappers around common scenarios. SwingWorker 并不特别,它只是一些常见场景的封装。 It will call invokeLater on your behalf so really both cases you present are just instances of the same thing.它将代表您调用 invokeLater,因此您提出的两种情况实际上只是同一事物的实例。

Just make sure you follow these two rules: 1. Don't stall the EDT 2. Perform Swing-related code on the EDT只需确保遵循以下两条规则: 1. 不要停止 EDT 2. 在 EDT 上执行 Swing 相关代码

That's indeed an interesting question and the accepted answer isn't fully responding it.这确实是一个有趣的问题,而公认的答案并没有完全回应它。

Both approaches you suggest are acceptable and will work fine, but I believe the first one is better than the second approach (do it all on the EDT, and if there is some long-running tasks do them on a SwingWorker, or a new thread if they're not related to Swing).您建议的两种方法都可以接受并且可以正常工作,但我相信第一种方法比第二种方法更好(在 EDT 上全部执行,如果有一些长时间运行的任务在 SwingWorker 或新线程上执行如果它们与 Swing 无关)。


Why?为什么? As @ThomasKrägler pointed out here :正如@ThomasKrägler 在这里指出的那样:

While you could split these tasks (model, controller and view creation) between main thread and EDT (and possibly gain a few milliseconds until the UI is first shown) it would also complicate the design of the application (multithreading is no easy topic) and litter the code base with invokeLater() calls.虽然您可以在主线程和 EDT 之间拆分这些任务(模型、controller 和视图创建)(并且可能会在 UI 首次显示之前获得几毫秒),但它也会使应用程序的设计复杂化(多线程不是一个简单的话题)和使用 invokeLater() 调用乱扔代码库。

Take into account that the EDT won't need to process anything until the model and controller are initialised (and thus starting the view too).考虑到 EDT 在 model 和 controller 初始化之前不需要处理任何东西(因此也启动了视图)。 So you can use the EDT to initialise them, as it won't have any negative impact on your UI (there is no UI yet).所以你可以使用 EDT 来初始化它们,因为它不会对你的 UI 产生任何负面影响(目前还没有 UI)。

Doing it this way, you'll save a lot of invokeLater calls and possible errors forgetting to call invokeLater .这样做,您将节省大量的invokeLater调用和可能忘记调用invokeLater的错误。 Your code will look much cleaner too.你的代码也会看起来更干净。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM