使用单独的线程更新JTable

4

这个应用程序的目的是查询一个表格,并将信息更新到JTable中。现在ThreadTask()已经能够查询表格并获取信息。我的问题是,如何使用从数据库获取的信息更新JTable GUI对象?

    public class AdminManager extends JFrame {

        public static void main(String[] args) throws InterruptedException {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        AdminManager frame = new AdminManager();
                        frame.setVisible(true);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                }
            });

            // Setup connection pool

            ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
            exec.scheduleAtFixedRate(new ThreadTask(connection), 2000, 100, TimeUnit.MILLISECONDS);
    }
        /**
         * Create the frame.
         */
        public AdminManager() {
            // Setup GUI

            DefaultTableModel model = new DefaultTableModel();
            model.addColumn("#");


            tableQueue = new JTable(model);
            tableQueue.getColumnModel().getColumn(0).setPreferredWidth(3);
            scrollPane.setViewportView(tableQueue);

        }
    class updateTable extends SwingWorker<Void, String> {
        @Override
        protected Void doInBackground() throws Exception {
            model.addRow(new Object[]{order_num});
            return null;
        }

    }
}
class grabData implements Runnable {
    private Connection connection;
    private DefaultTableModel model;
    private String order_num;

    public grabData(Connection c, DefaultTableModel m) {
         connection = c;
         model = m;
    }

    @Override
    public void run() {
       System.out.println("Working ... ");
       String sql = "SELECT * FROM order_queue;";
       Statement st;
       try {
           st = connection.createStatement();
           ResultSet rs = st.executeQuery(sql);
            while(rs.next()) {
                order_num = rs.getString("order_num");
                System.out.println(order_num);
                updateTable.execute()
            }
       } catch (SQLException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
       }   
   }
1个回答

9
如果您要向由可视化JTable持有的TableModel对象添加行,则必须在Swing事件线程(EDT)上执行此操作。如果您正在创建一个完全新的TableModel,即没有被可视化的表格模型,我认为安全的做法是在EDT之外填充它,然后将其设置为JTable的模型。
考虑一下,如果您想在JTable中逐个添加行而不是一次性添加所有行,可以考虑使用SwingWorker<Void, RowObject>,然后通过发布/处理方法对while (rs.next()) {获取的RowObject进行传递。
编辑:您也可以跳过SwingWorker,在EDT上排队添加表格的行:
while(rs.next()) {
    final String order_num = rs.getString("order_num");
    // System.out.println(order_num);
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        model.addRow(new Object[]{order_num});
      }      
    });
}

是的,我将向已创建的表中添加行。 - scriptdiddy
+1 for SwingWorker。@scriptdiddy:SwingWorker API 包括一个更新 TableModel 的示例。 - trashgod
我该如何从我的主类外部调用SwingWorker类,例如从ThreadTask类内部调用它? - scriptdiddy
@scriptdiddy:SwingWorker不必从Swing事件线程中调用,您可以在其上调用execute()以使其运行。它将在调用它的线程的后台线程上运行。但请注意,只要在事件线程中加载JTable中的内容,就无需使用SwingWorker。 - Hovercraft Full Of Eels
气垫船,现在我明白你的意思了...抱歉我有点困惑。我仍然在尝试将对象传递到线程中...例如,我添加了public grabData(Connection c, DefaultTableModel m)来包含表模型以添加它。这样做是正确的吗?再次感谢您的帮助! - scriptdiddy
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接