I have a class of my SwingWorker
where I want to update data in JTable
from DB:
public class MySwingWorker extends SwingWorker<Void, Monitor> {
public DBMonitor dbmonitor;
Vector<Vector> rowData;
Vector<String> columnNames;
DefaultTableModel model;
Monitor obj;
@Override
protected Void doInBackground() throws Exception {
dbmonitor = new DBMonitor();
rowData = dbmonitor.getJobsData();
columnNames = dbmonitor.getColumnNames();
obj.setJTable(rowData, columnNames);
while (!isCancelled()) {
Thread.sleep(10000);
JOptionPane.showMessageDialog(null, "SLEEP!");
rowData = dbmonitor.getJobsData();
columnNames = dbmonitor.getColumnNames();
model = new DefaultTableModel(rowData, columnNames);
publish(new Monitor(model));
}
return null;
}
@Override
protected void process(List<Monitor> monitors) {
Monitor monitor = monitors.get(monitors.size() - 1);
monitor.updateJTable(monitor.getModel());
}
}
And Monitor
class where I render Tabs
, JTable
and execute SwingWorker
:
public class Monitor extends JFrame{
TableModel model;
JTable jtable = null;
JTabbedPane jtp = null;
JPanel jp1 = null;
JPanel jp2 = null;
JLabel label1 = null;
JLabel label2 = null;
MySwingWorker worker;
public void setJTable(Vector data, Vector columnNames) {
jtable = new JTable(data, columnNames);
JScrollPane scrollPane = new JScrollPane(jtable);
jp1.add(scrollPane);
}
public void updateJTable(TableModel model) {
jtable = new JTable(model);
}
public Monitor() throws ClassNotFoundException, SQLException {
setTitle("Monitor System");
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
//Panel with tabs for navigation
jtp = new JTabbedPane();
getContentPane().add(jtp);
//tab1, info from dba_jobs
jp1 = new JPanel();
//tab2 info from QueueInfo
jp2 = new JPanel();
label1 = new JLabel();
label1.setText("tab1");
label2 = new JLabel();
label2.setText("tab2");
jp1.add(label1);
jp2.add(label2);
jtp.add("Tab1", jp1);
jtp.add("Tab2", jp2);
DBMonitor dbmonitor = new DBMonitor();
Vector<Vector> rowData = dbmonitor.getJobsData();
Vector<String> columnNames = dbmonitor.getColumnNames();
setJTable(rowData, columnNames);
setSize(600, 600);
setVisible(true);
(worker = new MySwingWorker()).execute();
}
public Monitor(TableModel model) {
this.model = model;
}
public TableModel getModel() {
return model;
}
}
And in my Main
method I execute:
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Monitor();
}
});
The problem is that, showMessageDialog()
doesn't append, and JTable
doesn't refresh.
I want update JTable
from DB every 10 sec. The Example I take from here
Your JTable
does not update because when publishing you create a new JFrame (called Monitor) and set the new TableModel
to it. You never show the new JFrame
, nor do you update the already existing one. Hence, of course, you won't see any updates.
As for how to do this properly:
SwingWorker
either a callback or a reference to the already existing Monitor
(explicit via a variable, or implicit by moving it into an inner class). Only then will you update the correct JFrame
JTable
every time your model changes and not replacing your component. I.E. your frame will still show the old table and have the data for a new one (but will not show it). You need to either replace the table in the updateTable
method, or (much better solution) update the model.EDIT
An example of how this can look like (Assuming your column names don't change, if they do send them over just like the rows):
public class Monitor extends JFrame{
TableModel model;
Vector<String> columnNames;
<other components>
public Monitor() throws SQLException {
columnNames = dbmonitor.getColumnNames();
model = new DefaultTableModel(columnNames, 0);
<Add all components, including table with the created table model>
(worker = new MySwingWorker()).execute();
}
private class MySwingWorker extends SwingWorker<Void, Vector<Vector>> {
@Override
protected Void doInBackground() throws Exception {
dbmonitor = new DBMonitor();
rowData = dbmonitor.getJobsData();
while (!isCancelled()) {
Thread.sleep(10000);
publish(dbmonitor.getJobsData());
}
return null;
}
@Override
protected void process(List<Vector<Vector>> data) {
Vector<Vector> lastPublish = data.get(data.size() - 1);
tableModel.setDataVector(lastPublish, columnNames);
}
}
}