Reputation: 3059
I have a JTable
which populates data from DB. I want to refresh data in JTable
every 10 minutes (for testing 10 sec is enough). I tried do it with a Thread
, but I found that it is not good idea, and I need to use SwingWorker
public class Monitor extends JFrame{
JTable jtable = null;
JTabbedPane jtp = null;
JPanel jp1 = null;
JPanel jp2 = null;
JLabel label1 = null;
JLabel label2 = null;
public void setJTable(Vector data, Vector columnNames) {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jtable = new JTable(data, columnNames);
JScrollPane scrollPane = new JScrollPane(jtable);
jp1.add(scrollPane);
}
public void updateJTable(Vector data, Vector columnNames) {
jtable = new JTable(data, columnNames);
}
public Monitor() {
setTitle("Monitor System");
//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);
}
}
And my Demo
class:
public class Demo {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Statement stmt = null;
Connection conn = null;
ResultSet rs = null;
Vector<String> columnNames = new Vector<String>();
Vector<Vector> rowData = new Vector<Vector>();
DBMonitor dbmonitor = new DBMonitor();
Monitor monitor = new Monitor();
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
rowData = dbmonitor.getJobsData();
columnNames = dbmonitor.getColumnNames();
monitor.setJTable(rowData, columnNames);
monitor.setSize((int) dim.getWidth(), (int) dim.getHeight());
monitor.setVisible(true);
boolean interrupt = true;
while (interrupt) {
try {
rowData = dbmonitor.getJobsData();
columnNames = dbmonitor.getColumnNames();
monitor.updateJTable(rowData, columnNames);
try {
Thread.sleep(10000);
} catch (InterruptedException ie) {
return;
}
JOptionPane.showMessageDialog(null, "SLEEP!");
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e.getMessage());
System.err.println(e.getMessage());
}
}
}
}
How I can do it with SwingWorker
? I don't get a concept of that way.
Upvotes: 0
Views: 2297
Reputation: 347194
First, I would start with a Timer
of some sort, I'm going to use a Swing Timer as it easy, but you could use a java.util.Timer
instead...
private Timer updateTimer;
//...
updateTimer = new Time(10000, new ActionListener() {
public void actionListener(ActionEvent e) {
}
});
updateTimer.setRepeats(false);
updateTimer.start();
This allows you to be notified in about 10 seconds time...
Then you need a SwingWorker
that can do the actual work...
public class UpdateWorker extends SwingWorker<TableModel, Void> {
private Monitor monitor;
private Timer updateTimer;
public UpdateWorker(Monitor monitor, Timer updateTimer) {
this.monitor = monitor;
this.updateTimer = updateTimer;
}
@Override
protected TableModel doInBackground() throws Exception {
Vector<Vector> rowData = dbmonitor.getJobsData();
Vector columnNames = dbmonitor.getColumnNames();
DefaultTableModel model = new DefaultTableModel(rowData, columnNames);
return model;
}
@Override
protected void done() {
try {
TableModel model = get();
monitor.updateTable(model);
} catch (InterruptedException | ExecutionException ex) {
ex.printStackTrace();
}
updateTimer.restart();
}
}
Now in the actionPerformed
method of the ActionListener
assigned to the timer, you would do something like..
public void actionListener(ActionEvent e) {
UpdateWorker worker = new UpdateWorker(monitor, this);
worker.execute();
}
To execute the worker. The reason for having a non-repeating timer is to ensure that the next update is set for n
seconds from when the update completes, so you don't get overlapping updates
Oh, and this will require to update your Monitor
to accept a TableModel
rather then the Vector
s you are using to create one, it's just simpler that way...
Upvotes: 1
Reputation: 324108
In the doInBackground()
method of the SwingWorker you have you while loop that:
publish()
method of the SwingWorker to pass the TableModel to the 'process()` method of your SwingWorkerThen in the process()
method of the SwingWorker you:
process()
method to update your JTable.Read the section from the Swing tutorial on Concurrency for more information and a working example or search the forum for more SwingWorker
examples.
Upvotes: 2