Mój "problem" można opisać następująco. Załóżmy, że mamy intensywny proces, który chcemy uruchomić w tle i zaktualizować pasek Swing JProgress. Rozwiązanie jest proste:Jak delegować publikację SwingWorker do innych metod
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);
}
}
Teraz przyjmijmy, że mam różne metody, które zajmują dużo czasu. Na przykład mamy metodę, która pobiera plik z serwera. Lub inny, który przesyła na serwer. Albo cokolwiek naprawdę. Jaki jest właściwy sposób delegowania metody publikowania do tych metod, aby mogły one odpowiednio zaktualizować GUI?
co znalazłem do tej pory jest to (zakładając, że metoda „aMethod” mieszka w innym opakowaniu, na przykład):
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();
}
}
}
}
To działa, ale wiem, że czegoś brakuje. jakieś pomysły?
co, jeśli mamy tylko jedną straszną długą metodę? Nie spadam, ale to nie jest rozwiązanie. – Xorty
Możesz zaniechać, jeśli moja odpowiedź jest zła. Ale przeczytałem w pytaniu "Na przykład mamy metodę, która pobiera plik z serwera lub inną, która ładuje się na serwer, lub coś naprawdę". ... więc przypuszczam, że jest wiele metod, nie tylko jeden straszny długi ? – Istao
Problem w tym, że te metody można wywołać z różnych części kodu. Element gui, którego będą potrzebować do odświeżenia, nie zawsze będzie taki sam. Dzięki mojemu rozwiązaniu mogę stworzyć ogólną metodę i za każdym razem, gdy tworzę nowy swingworker mogę przypisać metodę procesu na moim gui. –