Oto rozwiązanie problemu, przy pomocy klasy SwingWorker, dostępnej w Java SE (od wersji 6).
Idea jest następująca:
- Tworzymy obiekt SwingWorker
- nadpisujemy metodę doInBackground() - tu umieszczamy logikę, która może trwać dowolnie długo
- nadpisujemy metodę done() - tu dajemy kod modyfikujący kontrolki Swinga
- Całość uruchamimay przez metodę execute()
package pl.prv.wojsal.action;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import javax.swing.WindowConstants;
import org.apache.log4j.Logger;
import pl.prv.wojsal.utils.UtCzas;
import pl.prv.wojsal.utils.UtLog;
/**
* <pre>
* <ul>
* <li>Projekt: wsSwing
* <li>Klasa:
* <li>Opis: Obsluga akcji o dlugim czasie przetwarzania
* <li>Utworzono: 02-02-2014, 14:24:12
* <li>author: (c) Wojciech Salata
* </ul>
* </pre>
*/
public class ObslugaDlugiejAkcji {
private static Logger log = Logger.getLogger(ObslugaDlugiejAkcji.class.getName());
/**
*
* @param args
*/
public static void main(String[] args) {
UtLog.initLog4jForTests();
ObslugaDlugiejAkcji m = new ObslugaDlugiejAkcji();
m.run();
}
private JFrame fr;
/**
*
*/
private void run() {
JPanel panel = new JPanel();
final JLabel lb1 = new JLabel("Label chowany/pokazywany przez Bt1");
panel.add(lb1);
final JLabel lb2 = new JLabel("Label chowany/pokazywany przez Bt2");
panel.add(lb2);
JButton bt1 = new JButton("Button 1 (dluga akcja)");
bt1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
log.debug("Obsluga akcji bt1 - start");
final ObslugaDlugiejAkcji oa1 = new ObslugaDlugiejAkcji();
oa1.run();
// UtCzas.sleep("To jest zle - to musi byc w doInBackground()");
log.debug("Po oa1.run()");
SwingWorker<Object, Object> sw = new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
UtCzas.sleep("Czekamy na koniec akcji bt1");
log.debug("Koniec dlugiego przetwarzania bt1");
return null;
}
@Override
protected void done() {
boolean visible = lb1.isVisible();
lb1.setVisible(!visible);
oa1.dispose();
log.debug("Usuniete oa1");
}
};
sw.execute();
log.debug("Obsluga akcji bt1 - koniec");
}
});
panel.add(bt1);
JButton bt2 = new JButton("Button 2");
bt2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
log.debug("Obsluga akcji bt2 - start");
boolean visible = lb2.isVisible();
lb2.setVisible(!visible);
log.debug("Obsluga akcji bt2 - koniec");
}
});
panel.add(bt2);
this.fr = new JFrame();
fr.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
fr.getContentPane().add(panel);
fr.setSize(300, 200);
fr.setVisible(true);
}
/**
*
*/
protected void dispose() {
this.fr.dispose();
}
}