Der findes en overordnet tråd der styrer alt GUI (en singleton i JVM (eller per. applikation)?. Denne kalder man (f.eks. med invokeLater eller invokeAndWait) når man vil give "tasks" til Swing.
Well...ikke en singleton, men korrekt at der er én tråd som håndterer UI'en. Swing er IKKE trådsikkert implementeret, for det ville være en stor performancemæssig degradering, så for ikke at falde i alle de andre trådmæssige problemer, såsom race conditions, så skal denne ene tråd udføre alle opdateringer af brugerfladen.
Her er et eksempel:
import javax.swing.*;
public class Test extends JFrame {
private JLabel resultLabel;
private long num;
public Test(long num) {
super("Test");
this.num = num;
resultLabel = new JLabel("Calculating result");
getContentPane().add(resultLabel);
setSize(500, 100);
new Thread(new Runnable() {
public void run() {
long sum = 0;
for (long i = 1; i <= Test.this.num; i++) {
sum += i;
}
//Update the UI from within the Swing thread
SwingUtilities.invokeLater(new UIUpdater(sum));
}
}).start();
}
private class UIUpdater implements Runnable {
private long sum;
public UIUpdater(long sum) {
this.sum = sum;
}
public void run() {
resultLabel.setText("The sum of the numbers from 1 to " + num + " is " + sum);
}
}
private static class UIInstantiater implements Runnable {
private long num;
public UIInstantiater(long number) {
num = number;
}
public void run() {
new Test(num).setVisible(true);
}
}
public static void main(String args[]) {
if (args.length == 0) {
System.out.println("Usage: java Test <num>");
} else {
long num = Long.parseLong(args[0]);
SwingUtilities.invokeLater(new UIInstantiater(num));
}
}
}
Start programmet med et stort tal (på min maskine er 1000000000 passende):
robert@robert-laptop:~$ javac Test.java
robert@robert-laptop:~$ java Test 1000000000
Den starter brugerfladen op og fortæller, at den arbejder på problemet. Den starter så en tråd, som beregner summen af alle tal fra 1 til det givne tal (der findes smartere måder, men jeg skulle bare bruge et problem, som man kunne bruge noget tid på at løse). Der bruges en anden tråd, for at brugerfladen ikke skulle blive uresponsiv. Når tråden så har regnet færdig, skal den opdatere brugerfladen med resultatet, men det må kun Swing tråden, så et Runnable objekt bliver lagt i Swings jobkø.
Håber det er til at forstå, ellers må du sige til :-)