0

我制作了一个 java GUI 程序,并在该 GUI 上添加了一个 jList,以便通过调用添加一个项目在该 jList 上打印程序的输出

listBox.addElement(""); // where listBox is an instance of jList

但问题是在添加时项目没有显示。当程序即将结束时,它们会显示出来。

意思是,我通过单击“开始”按钮启动程序,然后完成整个处理,包括将项目添加到“listBox”但是当程序返回到“actionPerformed() " "开始" 按钮的 ActionListener 方法。

可以做什么以便在将项目添加到列表时立即显示它们。

上面的应用程序是多线程的。主线程启动 GUI,然后启动 10 个线程并将 jList 的“listModel”(DefaultListModel 的实例)传递给所有线程,以便每个线程可以通过调用“addElement(”)”方法将项目添加到列表中“列表模型”

实际上,listModel 是 DefaultListModel 类的子类(DefaultListModelSubClass)的一个实例。我已经覆盖了 addElement() 方法以使其“同步”,以便一次只有一个线程可以向其中添加一个项目。

4

3 回答 3

3

您可能正在尝试在Event Dispatching Thread处理 GUI 更新的线程中进行处理。您的处理正在锁定 GUI 更新,然后在处理完成时,适当的 GUI 更改会传播。为了让它工作,你需要在一个单独的线程中执行你的处理,并在EVT必要时与它进行通信。如果您有 Java 6 可用, SwingWorker将是执行此操作的最佳方式。

于 2009-10-23T20:50:44.087 回答
1

所有事件的重绘和处理都在 AWT 事件调度线程 (EDT) 上完成。如果不是这种情况,那么您将处理多线程,这对于 GUI 来说不是很实用。

解决方案是在另一个线程中运行您的阻塞处理。通过在 EDT 上使用java.awt.EventQueue.invokeLater. 由于这是多线程的,因此您需要非常小心。特别是常见的建议是更喜欢线程之间传输的对象的不变性,以避免必须锁定。也使用少量的宽锁而不是大量的小锁,但仍然要小心回调。

避免SwingWorker。它使演示变得简短。但是,对于生产代码,它会强制 GUI 和非 GUI 紧密耦合的设计。

于 2009-10-23T20:59:09.720 回答
1

这就是发生的事情

点击
   |
   -----> 动作执行
              |
              ----------------> 填写清单
                                        | 对于每个项目
                                        --------------------> jlist.addElement()
              |
              ----------------> 绘制 jlist

当列表的填充结束时,您会间接调用paint 方法。

如果您想在此之前获得结果,则必须在向列表添加元素时绘制列表。

正如 Stefan Kendall 提到的那样,使用 SwingWorker 将使您能够做到这一点。

一般来说,您所做的是同时使用另一个线程来“填充”列表,它不时告诉“绘画”线程更新 gui

点击
   |
   -----> 动作执行
              |
              ----------------> 填写清单
                                        | 对于每个项目
                                        --------------------> jlist.addElement()
                                             |
                                             | (在其他线程中)
                                             ----> 绘制列表(到目前为止的元素)

              |
              ----------------> 绘制 jlist

于 2009-10-23T20:59:20.967 回答