【问题标题】:Creating a new thread with parameters - Thread is created but it doesn't show the data使用参数创建一个新线程 - 线程已创建但它不显示数据
【发布时间】:2013-08-28 21:11:06
【问题描述】:

我有一个类,OutputTable,它负责显示一个包含先前计算结果的表 (jtable)。结果在另一个类(平滑类)中计算,然后将结果作为参数发送到 OutputTable 类。

我需要计算两次数据,对于这两次,我需要显示一个带有结果的 jtable。 计算结果时没有多线程。

由于我需要显示 2 个不同的表,并且在计算出一个数据后我想显示该表,因此我决定为每个表创建一个新线程。所以我在第一个数据处理完成后立即启动第一个线程,当第二轮数据处理完成后我启动第二个线程。

要处理的两个数据的数据结构不同,一个是ArrayList<Station>,另一个是TreeMap<Integer, ArrayList<Station>>

问题在于,只有在完成第二次数据处理时才会填充表(进程再次空闲),这使我得出结论,线程有问题。当第一个线程启动时,它只显示窗口布局,内部没有其他内容。当第二个线程启动时,两个表都会填充结果。

我使用的是 GUI,当用户按下开始按钮时,它会开始数据处理。 GUI 与

javax.swing.JFrame实现ActionListener、ItemListener

所以我的代码是:

public class OutputTable extends JFrame implements Runnable{

TreeMap<Integer, ArrayList<Station>> map;
ArrayList<Station> arrayStation;

    public OutputTable(TreeMap<Integer, ArrayList<Station>> map, ArrayList<Station> arrayStation) { 
        this.map = map;
        this.arrayStation = arrayStation;
    }

    public void run()
    {
        DefaultTableModel model = new DefaultTableModel() { 
            String[] columnsName = { /* my column names go here*/ }; 

            @Override 
            public int getColumnCount() { 
                return columnsName.length; 
            } 

            @Override 
            public String getColumnName(int index) { 
                return columnsName[index]; 
            } 
        }; 

        JTable table = new JTable(model); 
        add(new JScrollPane(table)); 
        setSize(1300, 700);
        setDefaultCloseOperation(HIDE_ON_CLOSE);
        setVisible(true); 

        if(map != null)
        {
            for (ArrayList<Station> arrayAux : map.values()) 
            {
                for(int a = 0; a<arrayAux.size(); a++)
                {
                    model.addRow(new Object[] { /* here I populate the table with my get methods*/ });
                }
            }
        }

        if(arrayStation != null)
        {
            for(int a = 0; a<arrayStation.size(); a++)
            {
                    model.addRow(new Object[] { /* here I populate the table with my get methods*/ });
            }
        }
    }

}

这是来自我启动线程的 GUI 代码

/* (where I start processing the data for the first time) */
Runnable r = new OutputTable(null, processme);

new Thread(r).start();

/* (I start processing data for a second time) */
Runnable r2 = new OutputTable(xpto, null);
new Thread(r2).start();

编辑:

如果我不清楚,我假装是在创建 jtable 后立即显示 jtable 中的数据,而不是在所有处理结束时,因为它现在正在发生,我不知道的原因明白。

【问题讨论】:

    标签: java multithreading swing concurrency


    【解决方案1】:

    Swing 是一个单线程环境,对 UI 的所有更新和交互都应在事件调度线程的上下文中执行。

    这也意味着阻止 EDT 的任何操作都将阻止 UI 开始更新/重绘或处理可能发生的任何新事件。

    更多详情请见Concurrency in Swing

    您应该使用SwingWorker,而不是使用ThreadRunnable。它提供了一种可以在后台线程中完成处理的方法,还提供了简单易用的方法,让您可以在 EDT 中处理结果。

    例如...

    public class StationListWorker extends SwingWorker<Void, Object[]> {
        // The data to be processed...
        private List<Station> stations;
        // The model the results are to be published to...
        private DefaultTableModel model;
        public StationListWorker(List<Station> stations, DefaultTabelModel model) {
            this.stations = stations;
            this.model = model;
        }
    
        protected Void doInBackground() throws Exception {
            // Process the data in the background thread...
            for (Station station : stations) {
                // Process the data...
                publish(new Object[]{...});
            }
            return null;
        }
    
        protected void publish(List<Object[]> rows) {
            // Published in the EDT
            for (Object[] row : rows) {
                model.addRow(row);
            }
        }
    }        
    

    然后在你的“框架”类中......

    StationListWorker stationListWorker = new StationListWorker(stations, model);
    stationListWorker.execute();
    

    就我个人而言,我会建立两个工作人员,一个负责处理要处理的每组数据。这将使修改处理和简化逻辑更容易 - 恕我直言

    我也想看看The Use of Multiple JFrames, Good/Bad Practice?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-04
      • 2013-07-19
      • 1970-01-01
      • 2020-03-26
      • 2012-10-19
      • 2016-04-06
      • 1970-01-01
      相关资源
      最近更新 更多