Io uso per monitorare un'attività di lunga durata aggiornando una barra di avanzamento. L'attività di lunga durata viene ovviamente eseguita in un thread di Swingworker.jProgressBar aggiornamento da SwingWorker
ho usato per programmare cose del genere:
public class MySwingWorkerClass extends SwingWorker<Void, Void> {
private JProgressBar progressBar;
public MySwingWorker(JProgressBar aProgressBar) {
this.progressBar = aProgressBar;
progressBar.setVisible(true);
progressBar.setStringPainted(true);
progressBar.setValue(0);
}
@Override
public Void doInBackground() {
//long running task
loop {
calculation();
progressBar.setValue(value);
}
return null;
}
@Override
public void done() {
progressBar.setValue(100);
progressBar.setStringPainted(false);
progressBar.setVisible(false);
}
}
ma di recente ho scoperto che avrei potuto farlo utilizzando il "setProgress" e definisce il cambiamento di proprietà e fare cose del genere
public class MySwingWorkerClass extends SwingWorker<Void, Void> {
private JProgressBar progressBar;
public MySwingWorker(JProgressBar aProgressBar) {
addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
progressBar.setValue((Integer) evt.getNewValue());
}
}
});
progressBar.setVisible(true);
progressBar.setStringPainted(true);
progressBar.setValue(0);
setProgress(0);
}
@Override
public Void doInBackground() {
//long running task
loop {
calculation();
setProgress(value);
}
return null;
}
@Override
public void done() {
setProgress(100);
progressBar.setValue(100);
progressBar.setStringPainted(false);
progressBar.setVisible(false);
}
}
La mia domanda è: il mio primo codice è accettabile o devo usare il setProgress per anyreason? Trovo il secondo codice più complicato e nel mio caso e non so se c'è un vantaggio o un motivo per usare il secondo.
Qualche consiglio?
MODIFICA Grazie per la risposta. Come sommario La prima soluzione è "errata" perché l'aggiornamento della barra di avanzamento viene eseguito all'esterno dell'EDT. La seconda soluzione è "corretta" perché l'aggiornamento della barra di avanzamento viene eseguito all'interno dell'EDT
Ora, in base alla risposta "interessante" di @mKorbel nel mio caso il mio calcolo restituisce risultati in testo HTML che "inserisco" (vedere this link). Il mio codice attuale è il seguente.
che pubblico (stringa) e il mio codice processo sembra che
@Override
protected void process(List<String> strings) {
for (String s : strings) {
try {
htmlDoc.insertBeforeEnd(htmlDoc.getElement(htmlDoc.getDefaultRootElement(), StyleConstants.NameAttribute, HTML.Tag.TABLE), s);
} catch (BadLocationException ex) {
} catch (IOException ex) {
}
}
}
Come posso riutilizzare @mKobel a fare lo stesso nel mio caso. Voglio dire che usa per sovrascrivere il rendering della tabella nel mio caso quale renderer devo sovrascrivere (jTextPane?) E come?
Penso che anche il tuo secondo approccio sia sbagliato. Stai utilizzando un listener per impostare il valore, che invocherà il listener, che imposterà il valore, che invocherà l'ascoltatore, ecc. Non sono sicuro che ciò accadrà, ma è sbagliato. In questo modo, non ottieni i vantaggi di SwingWorker, stai ancora impostando il valore della barra di avanzamento nell'EDT. –
['SwingWorker.publish (V ...)'] (http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html#publish%28V...%29) "Questo metodo deve essere utilizzato all'interno del metodo' doInBackground' per fornire risultati intermedi per l'elaborazione nel * Thread di invio eventi * all'interno del metodo di processo. " –
@Andrews Thompson: utilizzo la pubblicazione per "pubblicare" i risultati ma qui http://docs.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html per impostare un valore della barra di avanzamento usano setProgress e NON pubblicare, quindi? – HpTerm