Ich habe viel über Swing, Threading, invokeLater(), SwingWorker usw. gelesen, aber ich kann es einfach nicht verstehen, also habe ich versucht, ein wirklich einfaches Programm zur Veranschaulichung zu erstellen . Ich habe mir viele Beispiele angesehen, aber keine von ihnen scheint zu zeigen, was ich gerade versuche. Es ist lange her, dass ich in Java programmiert habe (ich habe wirklich nichts in Java gemacht, seit ich AP Informatik 2003 in der High School genommen habe), also bitte, nimm mich mit.Aktualisiere ich Swing-Komponente außerhalb von EDT?
Hier ist, was ich in meinem Beispiel versuche. Ich habe einen Button und ein Label, und wenn ich auf den Button klicke, möchte ich, dass das Programm für 3 Sekunden pausiert, bevor ich einen Punkt an den Text des Labels anschließe. Während dieser 3 Sekunden möchte ich, dass die GUI normal erscheint und weiterhin auf weitere Klicks reagiert. Hier ist, was ich schrieb:
import javax.swing.SwingWorker;
public class NewJFrame extends javax.swing.JFrame
{
private javax.swing.JButton jButton1;
private javax.swing.JLabel jLabel1;
public NewJFrame()
{
initComponents();
}
private void initComponents()
{
jButton1 = new javax.swing.JButton();
jLabel1 = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jButton1.setText("Button");
jButton1.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(java.awt.event.ActionEvent evt)
{
jButton1ActionPerformed(evt);
}
});
getContentPane().add(jButton1, java.awt.BorderLayout.CENTER);
jLabel1.setText("Text");
getContentPane().add(jLabel1, java.awt.BorderLayout.PAGE_END);
pack();
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)
{
SwingWorker worker=new SwingWorker()
{
protected Object doInBackground()
{
try{Thread.sleep(3000);}
catch (InterruptedException ex){}
return null;
}
};
worker.execute();
jLabel1.setText(jLabel1.getText()+".");
}
public static void main(String args[])
{
java.awt.EventQueue.invokeLater(new Runnable()
{
public void run(){ new NewJFrame().setVisible(true); }
});
}
}
mit diesem Code, wenn ich auf die Schaltfläche klicken, wird die Zeit unmittelbar auf dem Etikett angehängt, das macht Sinn für mich, weil ich schaffe und einen Hintergrund-Thread schlafen, so dass die EDT verfügbar, um das Etikett sofort zu aktualisieren. Also habe ich versucht, dies:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)
{
Thread thread = new Thread();
try{ thread.sleep(3000);}
catch (InterruptedException ex){}
jLabel1.setText(jLabel1.getText()+".");
}
Das funktioniert fast außer dass es blockiert die EDT verursacht die Taste drei Sekunden blau werden, bevor die Zeit auf dem Etikett der Text angehängt. Ich will nicht die Taste, um aussieht es für die ganzen 3 Sekunden gedrückt ist wird, wenn es wurde wirklich geklickt nur schnell, so dass ich versuchte, dies:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)
{
SwingWorker worker=new SwingWorker()
{
protected Object doInBackground()
{
try{Thread.sleep(3000);}
catch (InterruptedException ex){}
jLabel1.setText(jLabel1.getText()+".");
return null;
}
};
worker.execute();
}
Dies scheint zu funktionieren, sind aber nicht ich Aufruf jLabel1 .setText (...) vom Hintergrund-Thread und nicht vom EDT, und damit die "Swing Single Threading Rule?" Wenn ja, gibt es einen besseren Weg, um den gewünschten Effekt zu erzielen? Wenn nicht, können Sie bitte erklären warum?
+1 für Mühe und Forschung !! – MadProgrammer