Mi "problema" puede describirse de la siguiente manera. Supongamos que tenemos un proceso intensivo que queremos que se ejecute en segundo plano y le pedimos que actualice una barra Swing JProgress. La solución es fácil:Cómo delegar la publicación de SwingWorker a otros métodos
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
/**
* @author Savvas Dalkitsis
*/
public class Test {
public static void main(String[] args) {
final JProgressBar progressBar = new JProgressBar(0,99);
SwingWorker<Void, Integer> w = new SwingWorker<Void, Integer>(){
@Override
protected void process(List<Integer> chunks) {
progressBar.setValue(chunks.get(chunks.size()-1));
}
@Override
protected Void doInBackground() throws Exception {
for (int i=0;i<100;i++) {
publish(i);
Thread.sleep(300);
}
return null;
}
};
w.execute();
JOptionPane.showOptionDialog(null,
new Object[] { "Process", progressBar }, "Process",
JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE,
null, null, null);
}
}
Ahora supongo que tengo varios métodos que llevan mucho tiempo. Por ejemplo, tenemos un método que descarga un archivo de un servidor. U otro que sube a un servidor. O cualquier cosa realmente. ¿Cuál es la forma correcta de delegar el método de publicación a esos métodos para que puedan actualizar la GUI de manera adecuada?
lo que he encontrado hasta ahora es esto (a suponer que el método "aMethod" reside en algún otro paquete, por ejemplo):
import java.awt.event.ActionEvent;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
/**
* @author Savvas Dalkitsis
*/
public class Test {
public static void main(String[] args) {
final JProgressBar progressBar = new JProgressBar(0,99);
SwingWorker<Void, Integer> w = new SwingWorker<Void, Integer>(){
@Override
protected void process(List<Integer> chunks) {
progressBar.setValue(chunks.get(chunks.size()-1));
}
@SuppressWarnings("serial")
@Override
protected Void doInBackground() throws Exception {
aMethod(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
publish((Integer)getValue("progress"));
}
});
return null;
}
};
w.execute();
JOptionPane.showOptionDialog(null,
new Object[] { "Process", progressBar }, "Process",
JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE,
null, null, null);
}
public static void aMethod (Action action) {
for (int i=0;i<100;i++) {
action.putValue("progress", i);
action.actionPerformed(null);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Funciona pero sé que le falta algo. ¿Alguna idea?
¿y si tenemos solo un método terrible largo? No estoy bajoneando, pero esta no es una solución – Xorty
Puedes revocar si mi respuesta es mala. Pero leí en la pregunta "Por ejemplo, tenemos un método que descarga un archivo de un servidor u otro que se carga a un servidor. O algo realmente." ... así que supongo que hay muchos métodos, no solo uno terrible largo ? – Istao
El problema que tengo es que estos métodos se pueden llamar desde diferentes partes del código. Y el elemento GUI que necesitarán para actualizar no será siempre el mismo. Con mi solución puedo crear un método genérico y cada vez que creo un nuevo swingworker puedo evaluar el método de proceso en mi GUI. –