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
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" but开发者_如何学JAVAton 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.
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"
In actual, listModel is an instance of a subclass (DefaultListModelSubClass) of DefaultListModel class. I have override the addElement() method to make it "synchronized" so that at one time only one thread can add an item to that.
You're probably trying to do processing in the Event Dispatching Thread
, the thread that handles GUI updates. Your processing is locking the GUI from updating, and then when processing finishes, the proper GUI changes propagate. To get this to work, you'll need to perform your processing in a separate thread and communicate with the EVT
as necessary. SwingWorker will be the best way to do this, if you have Java 6 available.
All repainting and processing of events is done on the AWT Event Dispatch Thread (EDT). If that wasn't the case then you would by dealing with multithreading, and that is not very practical for a 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
. 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
. It makes demos short. However, for production code it forces a design where the GUI and non-GUI are tightly coupled.
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.
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.
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
click | -----> ActionPerformed | ----------------> Fill the list | for each item --------------------> jlist.addElement() | | ( in other thread ) ----> paint the list ( with the element so far ) | ----------------> paint the jlist
精彩评论