2

我的课程中有 3 个小学课程。第一个扩展小程序(并充当我的主),第二个是处理后端物流/与服务器通信的线程(实现 Runnable),第三个是 JPanel 类,它创建 GUI(这是创建的通过调用SwingUtilities.invokeAndWait()主(小程序)类在新线程中。

GUI 类与后端线程多次通信以获取要在屏幕上显示的数据。我的问题是 GUI 在后端类为它们提供数据之前显示其组件。所以,我想告诉 GUI 在另一个线程中调用一个方法,等待它的回复,然后显示它的组件。我尝试了几种变体:

Object[] data = backend.Method1(); 
wait();
showComponents(data);

在 GUI 类上,并放置notifyAll();在后端线程中 Method1 的底部,但我在 netbeans 中收到警告(在同步上下文之外调用 Object.wait),并且程序在java.lang.illegalmonitorstateexception运行时崩溃。我尝试将synchronized关键字添加到这两种方法中,但这会导致程序冻结。

我(显然,我敢肯定)只是在学习多线程:我在这里误解了什么?

我有一种感觉,JPanel 类没有实现可运行的相关。

编辑:根据@MadProgrammer 的建议,我正在使用一个 SwingWorker,它似乎在做这个伎俩。谢谢你指点我,我以前从未听说过他们。

 final JLabel loading = new JLabel("loading");
    loading.setVisible(true);
    add(loading);

    SwingWorker sw = new SwingWorker<Map<String, ArrayList<Time[]>>, Void>() {
        @Override
        public Map<String, ArrayList<Time[]>> doInBackground(){
            System.out.println("doing");
            Map<String, ArrayList<Time[]>> toReturn = dbh.getTimes(specToPass);
            return toReturn;
        }

        public void done(){
            try {
                loading.setVisible(false);
                Map<String, ArrayList<Time[]>> weekMap = new HashMap(this.get());
                showTimes(weekMap);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            } catch (ExecutionException ex) {
                  ex.printStackTrace();
            }
       }
    };
    sw.execute();

如果我没有正确实施,我希望你能告诉我。再次感谢。

4

1 回答 1

5

不。以任何方式阻止 UI 总是一个坏主意。这将使您的应用程序“挂起”并阻止 UI 更新(或响应用户的任何输入)。

这会造成非常糟糕的用户体验。

相反,使用某种回调,允许数据线程根据需要将更新发送回 UI。这应该允许您的 UI 在等待来自数据线程的数据时显示类似于“等待”消息的内容。

您也可以使用 aSwingWorker来处理数据收集,但它可能对您的所有需求来说很简单,但它提供了将任何更新同步回 UI 的简单方法。

确保与 UI 的所有创建/修改/交互都在事件调度线程的上下文中完成。

查看Swing 中的并发以获取更多详细信息

更新

基本工作流程(恕我直言)应该看起来像......

  • UI - 从后台线程请求数据,将侦听器接口传递给后台线程(使用类似loadingDoneloadingFailed的方法,例如
  • UI - 显示“加载”消息。可以显示一个漂亮的动画 GIF
  • 线程 - 加载数据时(假设一切顺利),将数据打包并通过loadingDone方法传回
  • UI -loadingDone调用时,与 EDT 重新同步(使用SwingUtilities.invokeLater)并更新 UI。

这实际上会更简单,SwingWorker它会提供内置的进度更新

于 2013-03-19T05:50:38.407 回答