I have created a simple JAVA Swing program that has a JTextArea, three JTextFields and one JButton. What this application does is when the user clicks the button it updates the JTextArea with a text line, the text line inserted into the JTextArea is prepared in a for loop and number of repeat times is given in a JTextField.
My problem is when I click the start JButton all the components of the application are freeze, I can't even close the window until the for loop completes it's job. How can I separate this JTextField updating work from other tasks in the form?
You are probably doing the work on the Event Dispatch Thread (the same thread as the GUI rendering is done). Use SwingWorker
it will do the work in another thread instead.
Code below produces this screenshot:
Example worker:
static class MyWorker extends SwingWorker<String, String> {
private final JTextArea area;
MyWorker(JTextArea area) {
this.area = area;
}
@Override
public String doInBackground() {
for (int i = 0; i < 100; i++) {
try { Thread.sleep(10); } catch (InterruptedException e) {}
publish("Processing... " + i);
}
return "Done";
}
@Override
protected void process(List<String> chunks) {
for (String c : chunks) area.insert(c + "\n", 0);
}
@Override
protected void done() {
try {
area.insert(get() + "\n", 0);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Example main
:
public static void main(String[] args) throws Exception {
final JTextArea area = new JTextArea();
JFrame frame = new JFrame("Test");
frame.add(new JButton(new AbstractAction("Execute") {
@Override
public void actionPerformed(ActionEvent e) {
new MyWorker(area).execute();
}
}), BorderLayout.NORTH);
frame.add(area, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
frame.setVisible(true);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With