我制作了一个java GUI程序并在该GUI上添加了一个jList,以便通过调用
添加项目来打印该jList上程序的输出listBox.addElement(""); // where listBox is an instance of jList
但问题是在添加时没有显示这些项目。当程序即将完成时,它们会被显示出来。
意思是,我通过单击“开始”按钮启动程序,然后完成整个处理,包括向“listBox”添加项目,但当程序返回到“j”时,项目显示在jList上actionPerformed()“”开始“按钮的ActionListener方法。
可以做什么以便在将项目添加到列表时立即显示这些项目。
上述应用程序是多线程的。主线程启动GUI然后启动10个线程并将jList的“listModel”(DefaultListModel的实例)传递给所有线程,以便每个线程可以通过调用“addElement(”“)”方法将项添加到列表中“listModel”
实际上,listModel是DefaultListModel类的子类(DefaultListModelSubClass)的实例。我已经覆盖了addElement()方法,使其“同步”,这样一次只有一个线程可以添加一个项目。
答案 0 :(得分:3)
您可能正在尝试在处理GUI更新的线程Event Dispatching Thread
中进行处理。您的处理是锁定GUI以免更新,然后在处理完成时,正确的GUI更改会传播。要使其工作,您需要在单独的线程中执行处理,并根据需要与EVT
进行通信。如果你有Java 6可用,SwingWorker将是最好的方法。
答案 1 :(得分:1)
所有重新绘制和处理事件都在AWT事件调度线程(EDT)上完成。如果情况并非如此,那么您将处理多线程,这对于GUI来说并不是很实用。
解决方案是在另一个线程中运行阻止处理。通过使用java.awt.EventQueue.invokeLater
在EDT上执行代码来更新GUI。因为这是多线程的,所以你需要非常小心。特别是,通常的建议是更喜欢在线程之间传输的对象的不变性,以避免必须锁定。也可以使用少量宽锁而不是许多小锁,但仍然要小心回调。
避免使用SwingWorker
。它使演示简短。但是,对于生产代码,它强制设计GUI和非GUI紧密耦合的设计。
答案 2 :(得分:1)
这就是发生的事情
click | -----> ActionPerformed | ----------------> Fill the list | for each item --------------------> jlist.addElement() | ----------------> paint the jlist
当列表填充结束时间接调用paint方法。
如果您想在此之前获得结果,则必须在向其添加元素时绘制列表。
使用SwingWorker作为Stefan Kendall提及将允许您这样做。
一般来说,你所做的是同时使用另一个线程作为列表“fill”,它不时告诉“绘画”线程更新gui
click | -----> ActionPerformed | ----------------> Fill the list | for each item --------------------> jlist.addElement() | | ( in other thread ) ----> paint the list ( with the element so far ) | ----------------> paint the jlist