...
Für die nachfolgend beschriebene Identifizierung der Swing-Komponenten, kann der verwendete AccessibleName aus den Property Dateien des Action & Command Framework ausgelesen werden. In der actions.properties
Datei wird der Name einer Action spezifiziert. Der dort verwendete Name der Action wird über die jadice implementation zu einem AccessibleName überführt. Anhand des Action Name bzw. des AccessibleName kann bei der Traversierung der Swing-Komponenten-Hierarchie die gesuchte Komponente identifiziert werden.
Nachfolgend ein ein auschnitt Auschnitt einer actions.properties
Datei, bei der der Action Name "Document drucken"(Zeile: 2) ausgelesen werden kann.
...
Der Action Name, bzw. Accessible Name kann wiederum im nachfolgend Dargestellten dargestellten "Erstellung der Policy anhand der Action Names" verwendet werden.
...
Im Beispiel "Erstellung der Policy anhand der Action Names" wird gezeigt, wie durch das hinzufügen Hinzufügen der Accessible Names in das String Array , die Fokusreihenfolge definiert werden kann. Die dort definierte Reihenfolge wird entspricht der Reihenfolge, mit der die Swing-Komponenten den Fokus erhalten.
AccessibleName aus dem Annotation Profil
Im falle Falle der AnnotationsToolbar, die dynamisch anhand des verwendeten annotation profile Annotationsprofil erstellt wird, kann der AccessibleName aus dem annoprofil Annotationsprofil ausgelesen werden (siehe Codebock "Auszug aus dem default-annotation-profile.xml"). Hierfür muss der Wert des attributes name (@name="Line") als AccessibleName verwendet werden (siehe Zeile 1).
Codeblock | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
<annotation-type name="Line" archetype="Line" class="com.levigo.jadice.annotation.LineAnnotation"> <renderer toolkit="swing" class="com.levigo.jadice.annotation.internal.renderer.LineAnnotationRenderer"/> <wrangler toolkit="swing" class="com.levigo.jadice.swing.internal.annotation.wranglers.LineAnnotationWrangler"/> <renderer toolkit="gwt" class="com.levigo.jadice.web.client.renderer.internal.annotation.LineAnnotationRenderer"/> <wrangler toolkit="gwt" class="com.levigo.jadice.web.client.internal.annotation.wrangler.LineAnnotationWrangler"/> ... <labels> <label locale="en">Line</label> <label locale="de">Linie</label> <label locale="fr">Ligne</label> <label locale="it">Linea</label> </labels> ... </annotation-type> |
...
In Swing sind die einzelnen Komponenten in einer Hierarchie, die einer Baumstruktur entspricht, enthalten. Wenn man beispielsweise angefangen beim Wurzelelement der Swing Hierarchie beginnt, durch die Elemente zu traversieren, kann man mittels des zuvor erwähnten AccessibleNames alle Elemente in dieser Baumstruktur wiederfinden. Ein Beispiel, wie so etwas angegangen werden kann, wird im Abschnitt "Beispiele" gezeigt. Wir verwenden im Beispiel dabei AtomicReferences (siehe https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicReference.html), um später Zugriff auf das Originalobjekt zu erhalten.
...
Nachfolgend wird beschrieben wie die erstellte Focus Traversal Policy Integriert werden kann. Es wird auch auf das verändern Verändern des Standard FocusTraversalKey eingegangen.
Setzen einer Focus Traversal Policy
Um eine FocusTraversalPolicy zu setzen, muss man nur die Policy auf der gewünschten Komponente setzen. Werden in der selben Hierarchie mehrere Komponenten mit einer Policy besetzt, so werden bei einem FocusTraversal diese Policies zunächst ignoriert. Wenn man die Beachtung dieser Policies wünscht, so kann man wie in dem gezeigten Beispiel es als PolicyProvider markieren. Dann wird bei einer Suche dessen Policy ebenfalls zur Anwendung kommen, falls diese Komponente zurückgegeben wird bei einer Suche (Next/First/Last Component).
Codeblock | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
// create a sample hierarchy with a frame that has a panel which has 2 buttons JFrame frame = new JFrame(); JPanel panel = new JPanel(); JButton comp1 = new JButton(); JButton comp2 = new JButton(); frame.add(panel); panel.add(comp1); panel.add(comp2); // set a FocusTraversalPolicy on the root of the hiearchy frame.setFocusTraversalPolicy(new ExampleTraversalPolicy()); // set a different Policy on the panel. By default it will not be used when the frame has the focus and it receives a focus change panel.setFocusTraversalPolicy(new ExamplePanelTraversalPolicy()); // by setting it as FocusTraversalPolicyProvider its policy will be taken into account when the panel is the component that should receive the focus next panel.setFocusTraversalPolicyProvider(true); |
Eigene FocusTraversalKeys verwenden
Standardmäßig wird TAB
verwendet, um bei der Komponente einen Fokuswechsel zur nächsten zu bewirken. Dies kann man durch das Setzen eigener Keys überschreiben. Über ein flag Boolean kann dabei gesteuert werden, ob die Komponente die Events des gesetzten Keys normal verarbeiten soll oder nur einen Fokuswechsel bewirken soll.
...
Zuvor wurde die Vorgehensweise beschrieben, bei der Anhand des AccessibleNames Komponenten , während der Traversierung der Swing-Komponenten-Hierarchie , aufgefunden und für eine FocusTraversalPolicy verwendet werden können. Diese Vorgehensweise ist nicht inn in allen Fällen anwendbar, weshalb nachfolgen Besonderheiten und Grenzen aufgezeigt werden.
...
Bei der Konstruktion einer Focus Traversal Policy muss man bestimmten dynamischen Komponenten besondere Beachtung schenken. Mit dynamischen Komponenten sind hier Komponenten gemeint, die dynamisch anhand von äußeren Faktoren wie beispielsweise einem gesetztem Annotationsprofil erzeugt werden. Ebenfalls können bestimmte Eigenschaften von Komponenten wie beispielsweise visuelle Sichtbarkeit oder ob die Komponente deaktiviert ist, eine Relevanz bei der Reihenfolge des Fokus haben. Diese müssen bei einer Policy je nach gewünschtem Verhalten gesondert beachtet werden.
...
Zum Beispiel die Annotationseditoren, das GalleryNavigationTool und die RolloutSearch unterstützen die in diesem Artikel Konzepte für die Tastaturbedienbarkeit momentan nicht. Wenn Sie diese dennoch in Ihrer Integration mit dem hier beschriebenen Konzept Verwenden wollen, stehen wir Ihnen gerne beraten zurseiteberatend zur Seite.
Fehlende AccessibleNames
Wenn eine Swing/AWT Komponente keinen AccesibleContext oder AccessibleName vergeben hat, kann dies die Identifizierung eines entsprechenden Elements , in dem Ansatz mit der Traversierung, erschweren. In diesem Fall müssen wahlweise andere Eigenschaften (AccessibleContext) einer Komponente vergeben werden, die diese in dem Hierarchiebaum eindeutig identifizierbar machen oder aber auf den Ansatz mit dem Halten von Referenzen auf die Objekte ohne Traversierung ausgewichen werden.
...
Bei einer komplexen Anwendung kommt es häufig dazu, dass ein sekundärer Dialog oder Frame zum Einsatz kommt. Da dieses Frame oder dieser Dialog nicht Teil der Hierarche des Hauptfensters ist, muss dieses ebenfalls eine eigene Policy mitbringen, die den Fokus steuert. Wichtig ist dabei auch den Übergang zwischen den Frames zu beachten. Soll beispielsweise dem neuen Fenster Focus gegeben werden, muss man mit requestFocus()
und gegebenenfalls toFront()
im Voraus aufgerufen werden um das Fenster in den Vordergrund zu rücken. Ob ein Fenster den Fokus letztendlich bekommt, kann jedoch je nach Betriebssystem anders gehandhabt werden und die Priorität des Fensters spielt ebenfalls eine Rolle.
...