...
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.
...
Codeblock | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.FocusTraversalPolicy; import java.awt.GridLayout; import java.awt.event.HierarchyEvent; import java.awt.event.HierarchyListener; import java.util.ArrayList; import java.util.List; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.SwingUtilities; public class AccesibleTraversal { public static void main(String[] args) { SwingUtilities.invokeLater(() -> { JFrame frame = new JFrame(); frame.setLayout(new GridLayout(0, 5)); // Create 5 buttons in order 3-1-4-2-5 List<Component> buttons = new ArrayList<>(); JButton button3 = new JButton("Button 3"); frame.add(button3); JButton button1 = new JButton("Button 1"); frame.add(button1); JButton button4 = new JButton("Button 4"); frame.add(button4); JButton button2 = new JButton("Button 2"); frame.add(button2); JButton button5 = new JButton("Button 5"); frame.add(button5); // Hold a list for the focus order of the buttons buttons.add(button1); buttons.add(button2); buttons.add(button3); buttons.add(button4); buttons.add(button5); frame.setFocusTraversalKeysEnabled(true); // Policy that uses the order of the list for switching focus frame.setFocusTraversalPolicy(new ButtonTraversalPolicy(buttons)); frame.setSize(new Dimension(500, 500)); frame.setVisible(true); }); } static class ButtonTraversalPolicy extends FocusTraversalPolicy { List<Component> components; public ButtonTraversalPolicy(List<Component> components) { this.components = components; } @Override public Component getComponentAfter(Container aContainer, Component aComponent) { int index = components.indexOf(aComponent); if (index >= 4) { return components.get(0); } else { return components.get(index + 1); } } @Override public Component getComponentBefore(Container aContainer, Component aComponent) { int index = components.indexOf(aComponent); if (index <= 0) { return components.get(components.size() - 1); } else { return components.get(index - 1); } } @Override public Component getFirstComponent(Container aContainer) { return components.get(0); } @Override public Component getLastComponent(Container aContainer) { return components.get(components.size() - 1); } @Override public Component getDefaultComponent(Container aContainer) { return components.get(0); } } } |
...
Codeblock | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
public static AtomicReference<Component> walkComponents(Container container, String nameToLookFor) { Component[] components = container.getComponents(); // iterate through child components of the current swing component for (int i = 0; i < components.length; i++) { AccessibleContext accessibleContext = components[i].getAccessibleContext(); if (accessibleContext != null) { String accessibleName = accessibleContext.getAccessibleName(); if (nameToLookFor.equals(accessibleName)) { // when a component is found we components[i].setFocusable(true); return new AtomicReference<>(components[i]); can set it to be focusable, so it can be used in the policy later on components[i].setFocusable(true); return new AtomicReference<>(components[i]); } } // search in den sub tree AtomicReference<Component> comp = walkComponents((Container) components[i], nameToLookFor); if (comp != null) { // when a component is found we can set it to be focusable, so it can be used in the policy later on comp.get().setFocusable(true); return comp; } } return null; } |
...
Codeblock | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
public class HierarchyFocusTraversalPolicy extends FocusTraversalPolicy { List<AtomicReference<Component>> order; public BasicDemoToolbarFocusTraversalPolicy(List<AtomicReference<Component>> order) { this.order = order; } @Override public Component getComponentAfter(Container aContainer, Component aComponent) { if (!order.isEmpty()) { int index = getIndex(aComponent); if (index == -1) { return getDefaultComponent(aContainer); } if (index + 1 < order.size()) { return order.get(index + 1).get(); } else { return getFirstComponent(aContainer); } } return null; } @Override public Component getComponentBefore(Container aContainer, Component aComponent) { if (!order.isEmpty()) { int index = getIndex(aComponent); if (index == -1) { return getDefaultComponent(aContainer); } if (index - 1 >= 0) { return order.get(index - 1).get(); } else { return getLastComponent(aContainer); } } return null; } @Override public Component getFirstComponent(Container aContainer) { if (!order.isEmpty()) { return order.get(0).get(); } return null; } @Override public Component getLastComponent(Container aContainer) { if (!order.isEmpty()) { return order.get(order.size() - 1).get(); } return null; } @Override public Component getDefaultComponent(Container aContainer) { return getFirstComponent(aContainer); } public int getIndex(Component component) { for (int index = 0; index < order.size(); index++) { if (component.equals(order.get(index).get())) { return index; } } return -1; } } |
...