Die Betrachtung des Documents soll mit einer Lösung zur Darstellung von Documents und deren Seiten in einer grafischen Oberfläche abgeschlossen werden. Ein Problem hierbei ist generell, dass zum Beispiel die Seitenliste Änderungen unterworfen sein kann, die nicht auf dem EventDispatchThread (EDT) von AWT/Swing oder SWT initiiert wurden. Die Herausforderung besteht nun darin, stets eine stabile und konsistente Version der Seitenliste für den EDT vorhalten zu müssen und diese Repräsentation nur so zu aktualisieren, dass die Änderungen jeweils während eines EDT-Zyklus für den EDT sichtbar werden. Um dies nicht wieder und wieder implementieren zu müssen, bietet jadice 5 eine Fassade, die dies erledigt und einem beliebigen Dokument vorangestellt werden kann: das UIDocument beziehungsweise für AWT/Swing das SwingUIDocument. Die Implementierung stützt sich unter anderem auf die GlazedLists-Basisklasse ThreadProxyEventList beziehungsweise SwingThreadProxyEventList. Benutzt man ein solches UIDocument zur »Versorgung« eines Objektes der Benutzeroberfläche, so vereinfacht sich diese Aufgabe gravierend:

  • Alle Änderungen der Seitenliste werden immer im Rahmen eines EDT-Zyklus sichtbar.

  • Die Notwendigkeit zum Locking beziehungsweise zur Synchronisation entfällt für alle rein lesenden Zugriffe.

  • Auch die Benachrichtigung über Änderungen über die Listener erfolgt immer auf dem EDT.

  • Dadurch können Oberflächenelemente direkt als Reaktion auf diese Änderungen aktualisiert werden, ohne SwingUtilities.invokeLater(...) oder Ähnliches benutzen zu müssen.

Wie werden UIDocuments nun konkret benutzt? Aus Performancegründen ist es wünschenswert, zu einem gegebenen Document generell immer nur ein einziges UIDocument vorzuhalten, ganz gleich, wie viele Oberflächenelemente bedient werden müssen. Wir haben deshalb den Zugriff auf das SwingUIDocument in eine statische Getter-Methode gekapselt: SwingUIDocument.get(myDocument). Code, der das UIDocument verwendet, könnte zum Beispiel wie folgt aussehen:

// zum Beispiel während der Initialisierung einer Applikation...
myDocument = new BasicDocument();
// [...]

// während der Initialisierung einer Swing-Oberflächenkomponente...
myComponent.add(new JLabel("Anzahl Seiten: "));

// Seitenanzahl darstellen und aktuell halten
final UIDocument<Component> uiDocument = SwingUIDocument.get(myDocument);
final JLabel pageCountLabel = new JLabel(
  Integer.toString(uiDocument.getPageCount())
);
uiDocument.addDocumentListener(new DocumentAdapter() {
  @Override
  public void listChanged(ListEvent<Page> listEvent) { 
    pageCountLabel.setText(Integer.toString(uiDocument.getPageCount()));
  }
});
// [...]

// Später irgendwann, auf einem beliebigen Thread...
myDocument.addPage(somePage);
myDocument.addPage(someOtherPage);
// [...]
[jadice® document platform 5 Dokumentation. Erstellungsdatum: 2011-08-12]
loading table of contents...