When a component is removed from the containment hierarchy, AWT automatically transfers focus elsewhere. Unfortunately, it doesn't do it gracefully like when a component is made invisible/disabled/etc...For those states, the code flows through autoTransferFocus() which first looks for other pending focus requests. This is not the case on removal. As such, even if you request focus elsewhere first, removing a component causes focus to go wherevere AWT wishes. Test case below:
Compile and run.
Put focus on the textfield with text "two"
Hit the button.
EXPECTED: focus should be on text field one, since it was requested before removing two
ACTUAL: focus is on the button due to AWT transfer
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class FocusTest extends JFrame {
public FocusTest() {
super("FocusTest");
setLayout(new GridLayout(3, 1));
final JTextField one = new JTextField("one");
final JTextField two = new JTextField("two");
JButton but = new JButton("Do It");
but.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
one.requestFocus();
getContentPane().remove(two);
((JPanel)getContentPane()).revalidate();
getContentPane().repaint();
}
});
getContentPane().add(one);
getContentPane().add(two);
getContentPane().add(but);
but.setRequestFocusEnabled(false);
}
private static void createAndShowGUI(String[] args) {
FocusTest test = new FocusTest();
test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
test.setSize(400, 400);
test.setLocationRelativeTo(null);
test.setVisible(true);
}
public static void main(final String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI(args);
}
});
}
}