SwingUtilities InvokeLater-什么被认为是不好的做法?
SwingUtilities InvokeLater- what is considered bad practice?
我有一个问题,关于使用 SwingUtilities 的 invokeLater 方法的正确做法是什么。
首先,我想确认一下我的理解是否正确。
据我了解,必须在 EDT 上更改 GUI,因为 Swing 组件不是线程安全的。 invokeLater 方法将 Runnable 作为参数,并且 运行nable 中包含的任何内容在 EDT 上都将是 运行。因此,对 Swing 组件的任何调用都放在一种队列中,在 EDT 上一次执行一个。
除此之外,我的问题是:使用它的最佳做法是什么?据我所知,至少有两种方法可以做到:
1) 在main
方法中,将所有代码,如GUI创建、Controller创建,甚至Model创建(假设是MVC类型模式)放在一个由invokeLater调用的Runnable中方法。当然,这是假设模型中的任何长 运行ning 任务都将使用 SwingWorker 执行。
2) GUI的创建放在invokeLater中,Controller的创建和Model的创建放在main
方法中。然后,每当您需要从 Controller 访问 Swing 组件时,您将在 invokeLater 方法中弹出所述代码以将其放入 EDT 队列。
这两种做法中的哪一种被认为是最佳做法或不良做法?如果这两个都不是很好,那么解决这个问题的更好方法是什么?
任何信息将不胜感激。
谢谢。
SwingWorker 并不特别,它只是一些常见场景的包装器。它会代表您调用 invokeLater,所以您提供的两种情况实际上只是同一事物的实例。
请务必遵守以下两条规则:
1. 不要拖延 EDT
2.在EDT
上执行Swing相关代码
这确实是一个有趣的问题,已接受的答案并未完全回应它。
您建议的两种方法都可以接受并且会很好地工作,但我相信第一种比第二种方法更好(在 EDT 上全部完成,如果有一些长运行 任务在 SwingWorker 上执行,如果与 Swing 无关,则在新线程上执行。
为什么? 正如@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 不需要处理任何内容。所以你可以使用 EDT 来初始化它们,因为它不会对你的 UI 产生任何负面影响(目前还没有 UI)。
这样做,您将节省大量 invokeLater
调用和忘记调用 invokeLater
的可能错误。您的代码也会看起来更简洁。
我有一个问题,关于使用 SwingUtilities 的 invokeLater 方法的正确做法是什么。
首先,我想确认一下我的理解是否正确。
据我了解,必须在 EDT 上更改 GUI,因为 Swing 组件不是线程安全的。 invokeLater 方法将 Runnable 作为参数,并且 运行nable 中包含的任何内容在 EDT 上都将是 运行。因此,对 Swing 组件的任何调用都放在一种队列中,在 EDT 上一次执行一个。
除此之外,我的问题是:使用它的最佳做法是什么?据我所知,至少有两种方法可以做到:
1) 在main
方法中,将所有代码,如GUI创建、Controller创建,甚至Model创建(假设是MVC类型模式)放在一个由invokeLater调用的Runnable中方法。当然,这是假设模型中的任何长 运行ning 任务都将使用 SwingWorker 执行。
2) GUI的创建放在invokeLater中,Controller的创建和Model的创建放在main
方法中。然后,每当您需要从 Controller 访问 Swing 组件时,您将在 invokeLater 方法中弹出所述代码以将其放入 EDT 队列。
这两种做法中的哪一种被认为是最佳做法或不良做法?如果这两个都不是很好,那么解决这个问题的更好方法是什么?
任何信息将不胜感激。
谢谢。
SwingWorker 并不特别,它只是一些常见场景的包装器。它会代表您调用 invokeLater,所以您提供的两种情况实际上只是同一事物的实例。
请务必遵守以下两条规则: 1. 不要拖延 EDT 2.在EDT
上执行Swing相关代码这确实是一个有趣的问题,已接受的答案并未完全回应它。
您建议的两种方法都可以接受并且会很好地工作,但我相信第一种比第二种方法更好(在 EDT 上全部完成,如果有一些长运行 任务在 SwingWorker 上执行,如果与 Swing 无关,则在新线程上执行。
为什么? 正如@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 不需要处理任何内容。所以你可以使用 EDT 来初始化它们,因为它不会对你的 UI 产生任何负面影响(目前还没有 UI)。
这样做,您将节省大量 invokeLater
调用和忘记调用 invokeLater
的可能错误。您的代码也会看起来更简洁。