简体   繁体   English

如何在Java中的jList上显示项目?

[英]How to show items on a jList in java?

I have made a java GUI program and have added a jList on that GUI so as to print output of the program on that jList by adding an item by calling 我已经制作了一个Java GUI程序,并在该GUI上添加了一个jList,以便通过调用添加项来在该jList上打印程序的输出

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

But the problem is that the items are not being displayed at the time of addition. 但是问题在于添加时没有显示项目。 They are being shown when the program is about to finish. 在程序即将完成时将显示它们。

Means, I am starting the program by clicking on a "Start" button and then the whole processing is done including the addition of items to the "listBox" but the items are shown on the jList when the program returns to the "actionPerformed()" method of the ActionListener of the "Start" button. 意思是,我通过单击“开始”按钮启动程序,然后完成了整个处理,包括将项目添加到“ listBox”中,但是当程序返回到“ actionPerformed()时,这些项目将显示在jList上“开始”按钮的ActionListener的“”方法。

What can be done so as to show the items instantly when they are added to the list. 将项目添加到列表中后可以立即显示这些项目。

The above application is multithreaded. 上面的应用程序是多线程的。 The main thread launch the GUI and then starts 10 threads and pass "listModel" (instance of DefaultListModel) of the jList to all the threads so that each thread can add items to the list by calling the "addElement("")" method on the "listModel" 主线程启动GUI,然后启动10个线程,并将jList的“ listModel”(DefaultListModel的实例)传递给所有线程,以便每个线程都可以通过调用on上的“ addElement(“”)“方法将项目添加到列表中“ listModel”

In actual, listModel is an instance of a subclass (DefaultListModelSubClass) of DefaultListModel class. 实际上,listModel是DefaultListModel类的子类(DefaultListModelSubClass)的实例。 I have override the addElement() method to make it "synchronized" so that at one time only one thread can add an item to that. 我重写了addElement()方法以使其“同步”,以便一次只能有一个线程可以向其中添加一项。

You're probably trying to do processing in the Event Dispatching Thread , the thread that handles GUI updates. 您可能正在尝试在Event Dispatching Thread进行处理,该线程用于处理GUI更新。 Your processing is locking the GUI from updating, and then when processing finishes, the proper GUI changes propagate. 您的处理正在锁定GUI,使其无法更新,然后在处理完成时,适当的GUI更改就会传播。 To get this to work, you'll need to perform your processing in a separate thread and communicate with the EVT as necessary. 为了使其正常工作,您需要在单独的线程中执行处理并根据需要与EVT通信。 SwingWorker will be the best way to do this, if you have Java 6 available. 如果您有Java 6,那么SwingWorker将是最好的方法。

All repainting and processing of events is done on the AWT Event Dispatch Thread (EDT). 事件的所有重绘和处理都是在AWT事件调度线程(EDT)上完成的。 If that wasn't the case then you would by dealing with multithreading, and that is not very practical for a GUI. 如果不是这种情况,那么您可以通过处理多线程来解决,这对于GUI来说不是很实际。

The solution is to run your blocking processing in another thread. 解决方案是在另一个线程中运行阻塞处理。 Update the GUI by executing code on the EDT with java.awt.EventQueue.invokeLater . 通过在EDT上使用java.awt.EventQueue.invokeLater执行代码来更新GUI。 As this is multithreaded you need to be very careful. 由于这是多线程的,因此需要非常小心。 In particular the common advice is to prefer immutability for object transferred between threads, so as to avoid having to lock. 特别是,通常的建议是,对于线程之间传输的对象,首选不变性,以避免必须锁定。 Also use few wide locks in preference to lots of small ones, but still be careful with callbacks. 还优先使用几个宽锁,而不是许多小锁,但在使用回调时仍要小心。

Avoid SwingWorker . 避免使用SwingWorker It makes demos short. 它使演示简短。 However, for production code it forces a design where the GUI and non-GUI are tightly coupled. 但是,对于生产代码,它会强制进行GUI和非GUI紧密耦合的设计。

This is what happens 这是怎么回事

click
   |
   -----> ActionPerformed
              |
              ---------------->  Fill the list 
                                        |    for each item 
                                        --------------------> jlist.addElement()
              |
              ----------------> paint the jlist

Indirectly you are invoking the paint method when the fill of the list ends. 当列表的填充结束时,您间接调用了paint方法。

If you want to have results before that, you'll have to paint the list as you add element to it. 如果要在此之前获得结果,则必须在为列表添加元素时绘制列表。

Using the SwingWorker as Stefan Kendall mentions will allow you to do this. 如Stefan Kendall所述,使用SwingWorker可以使您做到这一点。

In general terms what you do is concurrently using another thread for the list "fill" which from time to time tell the "painting" thread to update the gui 一般而言,您要做的是同时使用另一个线程作为列表“填充”,该线程不时告诉“绘画”线程更新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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM