Swing components freezing until one component completes its job
I have created a simple JAVA Swing program that has a JTextArea, three JTextFields and one JButton. What this application开发者_StackOverflow社区 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.
Example
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);
}
精彩评论