问题
I want JList to be populated with multiple threads. I tried this way but jlist is empty. It would be good if jlist was updated on the fly There are two threads, the other one loads in anouther direction
new Thread(new Runnable() {
@Override
public void run() {
for(i=0; i<cells.size()/2; i++){
System.out.println("thread");
try{
HtmlPage p = client.getPage("https://tbilisi.embassytools.com/en/slotsReserve?slot="+cells.get(i).getAttribute("data-slotid"));
pages.add(p);
if(!p.getUrl().toString().contains("slotsReserve"))
model.add(i,p.getUrl().toString());
}
catch (Exception e){
e.printStackTrace();
}
}
}
});
list1.setModel(model)
Thanks in advance
UPDATE* So I fixed by using SwingWorker
回答1:
Swing is a single threaded framework, that is, it is expected that all updates and modifications to the UI are done from within the context of the Event Dispatching Thread.
Equally, you should do nothing in the EDT that might block or otherwise prevent it from processing the Event Queue (like downloading content from the web).
This raise a conundrum. Can't update the UI outside the EDT, need to use some kind of background process to execute time consuming/blocking tasks...
So long as the order of items is unimportant, you would use multiple SwingWorker
s in place o of the Thread
s, for example...
DefaultListModel model = new DefaultListModel();
/*...*/
LoadWorker worker = new LoadWorker(model);
worker.execute();
/*...*/
public class LoaderWorker extends SwingWorker<List<URL>, String> {
private DefaultListModel model;
public LoaderWorker(DefaultListModel model) {
this.model = model;
}
protected void process(List<String> pages) {
for (String page : pages) {
model.add(page);
}
}
protected List<URL> doInBackground() throws Exception {
List<URL> urls = new ArrayList<URL>(25);
for(i=0; i<cells.size()/2; i++){
try{
HtmlPage p = client.getPage("https://tbilisi.embassytools.com/en/slotsReserve?slot="+cells.get(i).getAttribute("data-slotid"));
pages.add(p);
if(!p.getUrl().toString().contains("slotsReserve")) {
publish(p.getUrl().toString());
urls.add(p.getUrl());
}
}
catch (Exception e){
e.printStackTrace();
}
}
return urls;
}
}
This allows you execute your blocking/long running in the backround (doInBackground
) and publish
the results of this method which are then process
ed within the context of the EDT...
See Concurrency in Swing for more details
回答2:
Swing is not thread safe you should use SwingUtilities to run multiple threads updating swing.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
doWhateverYouWant();
}
});
read more
来源:https://stackoverflow.com/questions/19038721/populate-jlist-with-threads