Lo so che ci sono tutorial ed esempi, ma non riesco proprio ad applicarlo.
Da quello che mi dici tu, dovrei istanziare un oggetto che estende SwingWorker all'evento del premere il button e poi questo oggetto che costituisce il thread, chiamando da solo i metodi doInBackground() e done(), eseguirà il compito richiesto. Quindi una volta eseguito il done, il processo torna nella mani dell'EDT, giusto?
Ma se io ho implementato quest'oggetto che estende le SwingWorker in un'altra classe, in particolare in questa:
codice:
import java.awt.Toolkit;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.net.ConnectException;
import java.util.ArrayList;
import javax.xml.ws.WebServiceException;
import org.jdesktop.swingworker.SwingWorker;
import rubrica.bean.UserProfile;
import rubrica.jaxb.Contact;
import rubrica.manager.ContactsManager;
import rubrica.service.Persistence;
public class UpdateContactsThread_JFrame extends javax.swing.JFrame {
UserProfile userL = Persistence.getCurrentUserProfile();
ContactsManager contactsManager = new ContactsManager(userL);
ArrayList<Contact> contatti = new ArrayList();
SimpleTableModel tableModel = null;
/** Creates new form UpdateContactsThread_JFrame */
public UpdateContactsThread_JFrame() {
initComponents();
progressBar.setMinimum(0);
progressBar.setMaximum(100);
//Call setStringPainted now so that the progress bar height
//stays the same whether or not the string is shown.
progressBar.setStringPainted(true);
task = new Task();
task.addPropertyChangeListener(
new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
int progress = (Integer) evt.getNewValue();
progressBar.setIndeterminate(false);
progressBar.setValue(progress);
}
}
});
task.execute();
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jPanel1 = new javax.swing.JPanel();
progressBar = new javax.swing.JProgressBar();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Attendere prego...");
org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.add(progressBar, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 269, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addContainerGap(19, Short.MAX_VALUE))
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.add(progressBar, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(layout.createSequentialGroup()
.add(18, 18, 18)
.add(jPanel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(layout.createSequentialGroup()
.addContainerGap()
.add(jPanel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
private Task task;
class Task extends SwingWorker<SimpleTableModel, Void> {
/*
* Main task. Executed in background thread.
*/
@Override
public SimpleTableModel doInBackground() {
try {
contactsManager.update();
contatti = (ArrayList<Contact>) contactsManager.loadContacts();
tableModel = new SimpleTableModel(contatti);
return tableModel;
} catch (WebServiceException ex) {
ex.printStackTrace();
} catch (ConnectException ex) {
ex.printStackTrace();
}
return null;
}
/*
* Executed in event dispatch thread
*/
@Override
public void done() {
Toolkit.getDefaultToolkit().beep();
setCursor(null); //turn off the wait cursor
}
}
// Variables declaration - do not modify
private javax.swing.JPanel jPanel1;
private javax.swing.JProgressBar progressBar;
// End of variables declaration
}
Ho sovrascritto i metodi doInBackground() e done() per come mi servono a me. In particolare, al primo faccio restituire un SimpleTableModel che vorrei poi fosse passato all'EDT per aggiornare un componente dell'interfaccia. Dovrei usare il metodo publish(), ma dove lo devo mettere? nel doInBackground() o altrove?
E poi nell'interfaccia principale dove è presente il button cliccando il quale deve partire questo thread che mi dovrebbe visualizzare la progressBar per la durata del suo processo, oltre questo:
codice:
private void btnUpdateActionPerformed(java.awt.event.ActionEvent evt) {
btnUpdate.setEnabled(false);
setCursor(new Cursor(Cursor.WAIT_CURSOR));
UpdateContactsThread_JFrame updateThread = new UpdateContactsThread_JFrame();
updateThread.setVisible(true);
}
Cosa ci devo scrivere?
E' vero che ci sono esempi e tutorial, ma ripeto non riesco ad applicarmi al mio caso, forse semplicemente perchè tutto ciò che è presente in internet esegue tutto in una sola classe e quindi ha tutto lì a portata di mano, io no.