【问题标题】:Populate JList with threads用线程填充 JList
【发布时间】:2013-09-26 21:07:57
【问题描述】:

我希望 JList 填充多个线程。 我试过这种方式,但 jlist 是空的。 如果 jlist 即时更新就好了 有两根螺纹,另一根向另一个方向加载

            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)

提前致谢

更新* 所以我使用 SwingWorker 修复了

【问题讨论】:

  • 你没有start()你的线程。而且你不应该那样做,因为 Swing 不是线程安全的。阅读“SwingWorker”

标签: java arrays multithreading jlist defaultlistmodel


【解决方案1】:

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

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

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

只要项目的顺序不重要,您可以使用多个SwingWorkers 代替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) 和 publish 此方法的结果,然后在 EDT 的上下文中 processed...

详情请见Concurrency in Swing

【讨论】:

    【解决方案2】:

    Swing 是 not thread safe应该使用 SwingUtilities 运行多个线程来更新 swing。

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

    read more

    【讨论】:

      猜你喜欢
      • 2012-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多