启动Java Swing桌面应用程序的正确方法

4

如何启动需要从数据库检索初始数据5-10秒的应用程序?这是我目前所拥有的,但我不确定是否有更好的方法。我希望GUI和数据库访问在不同的线程中,以便GUI构建与数据检索同时进行。

public static void main(String[] args) {
    final Controller controller = new Controller();
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            View frame = new View();
            controller.setView(frame);
        }
    });
    Model model = new Model();
    controller.setModel(model);
    controller.getInitialData();
}

3
我不确定我理解问题是什么。您需要设计您的GUI,以便在完成数据库访问时它可以对模型中的更改做出反应。就像JTable监听TableModel的事件一样,您的整体UI应该监听来自模型的事件(例如“DB访问完成”)。 - Darien
3
在GUI界面加载之前,您可以展示一个“启动画面”(splash screen)来提示数据正在加载。否则,您也可以启动GUI界面,将其冻结并在数据加载期间显示一些信息。 - toto2
2
是的,一定要在单独的线程中处理数据库工作。我想你的getInitialData方法体应该创建一个SwingWorker并从其中获取数据,然后如上面的评论所提到的那样,在操作完成时通知GUI。 - Hovercraft Full Of Eels
所有这些都是很好的建议。 - mre
1个回答

9
你的方向有点对。希望这能让事情更清晰一些...
Swing不是线程安全的。话虽如此,你还有几个选择。其中之一是使用 SwingUtilities在事件分发线程上发布一个Runnable任务来执行。这将使你能够从数据库检索数据并在单独的线程中更新UI,同时尊重Swing的单线程模型。
SwingUtilities.invokeLater(new Runnable(){
    @Override
    public void run(){
        //  update UI
    } 
});

另一种选择,由于这是一个长时间运行的任务,可以使用 SwingWorker 在完成任务时或处理过程中向UI提供更新。

正如您所看到的,这两种机制(即SwingUtilitiesSwingWorker)都可以让您将这些任务分配给其他线程,同时为您提供在稍后(并且安全地)执行结果(通常转化为操作)的能力。无论您选择哪种方式,重要的是要记住,长时间运行的任务不应该在EDT中进行。因此,正如我所发现的那样,任何设计良好的GUI最重要的特性是响应性


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接