RandomData
RandomDataDemo is an example of using SwingWorker to load data via JDBC in a background thread. More on concurrency in Swing may be found here and here.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;
import org.h2.jdbcx.JdbcDataSource;
/**
* @author John B. Matthews
*/
public class RandomDataDemo {
private static final String RUN = "Run";
private static final String CANCEL = "Cancel";
private static final String QUIT = "Quit";
private static final JProgressBar progressBar = new JProgressBar();
private static final JTextArea textArea = new JTextArea(48, 120);
private static final JButton run = new JButton(CANCEL);
private static RandomDataTask task;
public static void main(String[] args) throws Exception {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
init();
}
});
}
private static void init() {
JFrame frame = new JFrame("Random Data Demo");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
progressBar.setIndeterminate(true);
frame.add(progressBar, BorderLayout.NORTH);
textArea.setEditable(false);
textArea.setFont(new Font("Monospaced", Font.PLAIN, 12));
frame.add(new JScrollPane(textArea), BorderLayout.CENTER);
JPanel panel = new JPanel();
run.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
if (RUN.equals(cmd)) {
task.cancel(true);
execTask();
run.setText(CANCEL);
} else {
task.cancel(true);
run.setText(RUN);
}
}
});
panel.add(run);
JButton quit = new JButton(QUIT);
quit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
task.cancel(true);
System.exit(0);
}
});
panel.add(quit);
frame.add(panel, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
execTask();
}
private static void execTask() {
textArea.replaceRange(null, 0, textArea.getSelectionEnd());
progressBar.setIndeterminate(false);
task = new RandomDataTask(2500);
task.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
progressBar.setValue((Integer) evt.getNewValue());
}
}
});
task.execute();
}
/**
* Get pseudo-random numbers from a data source.
*/
private static class RandomDataTask
extends SwingWorker<List<Double>, Double> {
private static final int BLOCK_SIZE = 10;
private final int count;
private final List<Double> numbers;
private int index = 1;
private Connection conn;
private PreparedStatement ps;
private ResultSet rs;
RandomDataTask(int count) {
this.count = count;
this.numbers = new ArrayList<Double>(count);
JdbcDataSource ds = new JdbcDataSource();
ds.setURL("jdbc:h2:file:~/src/java/jdbc/test;IFEXISTS=TRUE");
ds.setUser("sa");
ds.setPassword("");
try {
this.conn = ds.getConnection();
ps = conn.prepareStatement(
"SELECT RAND() FROM SYSTEM_RANGE(1, ?)");
ps.setInt(1, BLOCK_SIZE);
} catch (SQLException ex) {
ex.printStackTrace(System.err);
}
}
@Override
public List<Double> doInBackground() {
try {
for (int i = 0; i < count / BLOCK_SIZE; i++) {
rs = ps.executeQuery();
while (rs.next() && !isCancelled()) {
if (rs.getBoolean(1)) {
double number = rs.getDouble(1);
numbers.add(number);
setProgress(100 * numbers.size() / count);
publish(number);
}
}
Thread.sleep(10); // simulate latency
}
} catch (SQLException ex) {
ex.printStackTrace(System.err);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
return numbers;
}
@Override
protected void process(List<Double> chunks) {
StringBuilder strBuilder = new StringBuilder();
for (double number : chunks) {
strBuilder.append(String.format("%1$11.8f", number));
if (index % BLOCK_SIZE == 0) {
strBuilder.append('\n');
}
index++;
}
textArea.append(strBuilder.toString());
}
@Override
protected void done() {
run.setText(RUN);
}
}
}
Copyright © 2009 John B. Matthews. Distributed under the terms of the GPL