[Swing] How to implement tab order?
Hi Swing specialists
I have a JFrame (see TabOrderFrame below) containing several panels. All
these panels are separate classes (TabOrderPanel1 and TabOrderPanel2
extending JPanel).
Now I'd like to move the focus to the next field by pressing TAB.
However, I don't want to list all text fields (and combo boxes) within
the frame. Instead within the TabOrderFrame class I'd like to specify
the order of the panels and within a panel class (e.g. TabOrderPanel1)
I'd like to specify the order of its text fields.
What is the preferred way to do this? I post 3 classes that demonstrate
what I want, however, it apparently doesn't work that way.
Thanks in advance for any help on that.
Christian
/*
* TabOrderFrame.java
*/
import java.awt.*;
import javax.swing.*;
public class TabOrderFrame extends JFrame {
private TabOrderPanel1 panel1;
private TabOrderPanel2 panel2;
public TabOrderFrame() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(new GridBagLayout());
getContentPane().add(Box.createHorizontalStrut(150), new
GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST,
GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
panel1 = new TabOrderPanel1();
getContentPane().add(panel1, new GridBagConstraints(0, 1, 1,
1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
new Insets(2, 2, 2, 2), 0, 0));
JSeparator separator = new JSeparator(JSeparator.HORIZONTAL);
separator.setForeground(Color.BLACK);
getContentPane().add(separator, new GridBagConstraints(0, 2,
1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
new Insets(5, 2, 5, 2), 0, 0));
panel2 = new TabOrderPanel2();
getContentPane().add(panel2, new GridBagConstraints(0, 3, 1,
1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
new Insets(2, 2, 2, 2), 0, 0));
setFocusTraversalPolicy(new TabTraversalPolicy());
setFocusCycleRoot(true);
}
class TabTraversalPolicy extends FocusTraversalPolicy {
public Component getDefaultComponent(Container focusCycleRoot) {
return panel1;
}
public Component getFirstComponent(Container focusCycleRoot) {
return panel1;
}
public Component getLastComponent(Container focusCycleRoot) {
return panel2;
}
public Component getComponentAfter(Container focusCycleRoot,
Component aComponent) {
if (aComponent.getParent().equals(panel1)) {
return panel2;
} else if (aComponent.getParent().equals(panel2)) {
return panel1;
}
return panel1;
}
public Component getComponentBefore(Container focusCycleRoot,
Component aComponent) {
if (aComponent.equals(panel1)) {
return panel2;
} else if (aComponent.equals(panel2)) {
return panel1;
}
return panel1;
}
}
public static void main(String[] args) {
Frame f = new TabOrderFrame();
f.pack();
f.setVisible(true);
}
}
/*
* TabOrderPanel1.java
*/
import java.awt.*;
import javax.swing.*;
public class TabOrderPanel1 extends JPanel {
JTextField comp1;
JComboBox comp2;
JTextField comp3;
public TabOrderPanel1() {
setLayout(new GridLayout(3, 1));
comp1 = new JTextField("");
add(comp1);
comp2 = new JComboBox(new String[] {"10", "16", "20"});
add(comp2);
comp3 = new JTextField("");
add(comp3);
setFocusTraversalPolicy(new TabTraversalPolicy());
setFocusable(true);
setFocusCycleRoot(false);
}
class TabTraversalPolicy extends FocusTraversalPolicy {
public Component getDefaultComponent(Container focusCycleRoot) {
return comp1;
}
public Component getFirstComponent(Container focusCycleRoot) {
return comp1;
}
public Component getLastComponent(Container focusCycleRoot) {
return comp3;
}
public Component getComponentAfter(Container focusCycleRoot,
Component aComponent) {
if (aComponent.equals(comp1)) {
return comp3;
} else if (aComponent.equals(comp2)) {
return comp3;
} else if (aComponent.equals(comp3)) {
return comp1;
}
return comp1;
}
public Component getComponentBefore(Container focusCycleRoot,
Component aComponent) {
if (aComponent.equals(comp1)) {
return comp3;
} else if (aComponent.equals(comp2)) {
return comp1;
} else if (aComponent.equals(comp3)) {
return comp2;
}
return comp1;
}
}
}
/*
* TabOrderPanel2.java
*/
import java.awt.*;
import javax.swing.*;
public class TabOrderPanel2 extends JPanel {
JTextField comp1;
JComboBox comp2;
JTextField comp3;
public TabOrderPanel2() {
setLayout(new GridLayout(3, 1));
comp1 = new JTextField("");
add(comp1);
comp2 = new JComboBox(new String[] { "10", "16", "20" });
add(comp2);
comp3 = new JTextField("");
add(comp3);
setFocusTraversalPolicy(new TabTraversalPolicy());
setFocusCycleRoot(false);
}
class TabTraversalPolicy extends FocusTraversalPolicy {
public Component getDefaultComponent(Container focusCycleRoot) {
return comp1;
}
public Component getFirstComponent(Container focusCycleRoot) {
return comp1;
}
public Component getLastComponent(Container focusCycleRoot) {
return comp3;
}
public Component getComponentAfter(Container focusCycleRoot,
Component aComponent) {
if (aComponent.equals(comp1)) {
return comp2;
} else if (aComponent.equals(comp2)) {
return comp3;
} else if (aComponent.equals(comp3)) {
return comp1;
}
return comp1;
}
public Component getComponentBefore(Container focusCycleRoot,
Component aComponent) {
if (aComponent.equals(comp1)) {
return comp3;
} else if (aComponent.equals(comp2)) {
return comp1;
} else if (aComponent.equals(comp3)) {
return comp2;
}
return comp1;
}
}
}