Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update JTable with Separate Thread

The purpose of the application is to query a table, and take that information and update a JTable. Right now the ThreadTask() is able to query the table and obtain the information. My question is how do I update the JTable GUI object with the information obtained from the database?

    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();
       }   
   }
like image 730
scriptdiddy Avatar asked Jan 17 '23 04:01

scriptdiddy


1 Answers

If you are adding rows to a TableModel object that is held by a visualized JTable, then you must do so on the Swing event thread, the EDT. If you're creating a completely new TableModel one that isn't visualized, then I think it is safe to fill it off of the EDT, and then set it as the JTable's model on the EDT.

One consideration, if you want to add rows the JTable as they become available, consider using a SwingWorker<Void, RowObject>, and then pass the RowObject obtained in the while (rs.next()) { via a publish/process method pair.

Edit:
You could just skip the SwingWorker and just queue up adding the table's row on the 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});
      }      
    });
}
like image 177
Hovercraft Full Of Eels Avatar answered Jan 18 '23 23:01

Hovercraft Full Of Eels