Własna java.awt.FocusTraversalPolicy
W przypadku przenoszenia fokusu pomiędzy komponentami Swing
czasem konieczne jest zastosowanie własnej polityki określającej sposób i kolejność przenoszenia fokusu.
Klasy
Klasa NewFocusTraversalPolicy
package java_awt_focustraversalppolicy; import java.awt.*; import java.util.*; import javax.swing.*; //Jeżeli użyjemy klawisza tab to fokus będzie się //przenosił jedynie miedzy elementami umieszczonymi //w wektorze w takiej kolejności w jakiej one sa w nim //umieszczone @SuppressWarnings("SuspiciousMethodCalls") public class NewFocusTraversalPolicy extends FocusTraversalPolicy { private final Vector<JComponent> order; public NewFocusTraversalPolicy(Vector<JComponent> order) { this.order = new Vector<>(order.size()); this.order.addAll(order); } @Override public Component getComponentAfter(Container focusCycleRoot, Component component) { int idx = (order.indexOf(component) + 1) % order.size(); return order.get(idx); } @Override public Component getComponentBefore(Container focusCycleRoot, Component component) { int idx = order.indexOf(component) - 1; if (idx < 0) { idx = order.size() - 1; } return order.get(idx); } @Override public Component getDefaultComponent(Container focusCycleRoot) { return order.get(0); } @Override public Component getFirstComponent(Container focusCycleRoot) { return order.get(0); } @Override public Component getLastComponent(Container container) { return order.lastElement(); } }
Klasa Main
package java_awt_focustraversalppolicy; import java.awt.*; import java.util.*; import javax.swing.*; public class Main extends JFrame { private static final long serialVersionUID = 5990924180312145579L; public Main() { setLayout(new FlowLayout()); Vector<JComponent> vector = new Vector<>(); JButton[] buttons = new JButton[11]; // dodanie komponentów które będą miały focus // i w takiej kolejności w jakiej ten fokus // będzie przekazywany for (int i = 0; i < 11; i++) { buttons[i] = new JButton(Integer.toString(i)); add(buttons[i]); if (i % 2 == 0) { vector.add(buttons[i]); } } NewFocusTraversalPolicy policy = new NewFocusTraversalPolicy(vector); setFocusTraversalPolicy(policy); setBounds(10, 100, 300, 500); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(Main::new); } }
Wynik
W klasie Main
dodajemy do wektora co drugi przycisk, tworzymy klasę polityki.
Gdy uruchomimy klasę i klawiszem tab
będziemy zmieniali fokus, zobaczymy, że fokus otrzymują tylko przyciski umieszczone w wektorze.
Na wideo pokazano wynik kilkukrotnego naciśnięcia przycisku TAB