1

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

4

2 回答 2

1

Swing 是一个单线程框架,也就是说,对 UI 的所有更新和修改都应该在 Event Dispatching Thread 的上下文中完成。

同样,您不应在 EDT 中执行任何可能阻止或以其他方式阻止它处理事件队列的操作(例如从 Web 下载内容)。

这就提出了一个难题。无法在 EDT 之外更新 UI,需要使用某种后台进程来执行耗时/阻塞的任务...

只要项目的顺序不重要,您就可以使用多个SwingWorkers 来代替 o 的Threads,例如...

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;
    }
} 

这允许您在后台 ( doInBackground)中执行阻塞/长时间运行,然后在 EDT 的上下文中编辑publish此方法的结果...process

有关更多详细信息,请参阅Swing 中的并发

于 2013-09-26T21:32:07.143 回答
0

Swing不是线程安全的,您应该使用 SwingUtilities 运行多个线程来更新 swing。

javax.swing.SwingUtilities.invokeLater(new Runnable() {
    public void run() {
      doWhateverYouWant();
    }
});

阅读更多

于 2013-09-26T21:16:52.973 回答