如何立即让我的Swing组件获得焦点?requestFocus()
似乎不能立即调用。
理想情况下,我希望从EDT运行以下代码:
textInput.requestFocusInWindow();
System.out.println(textInput.hasFocus());
打印true
。
以下是SSCCE。注/要求:
- 使用键盘导航表格。列C2具有复合编辑器。
- 当我在C2列输入字母时,开始编辑。复合编辑器内的文本组件获得焦点。需要在标有“Trick”的注释中实现此点。
- 文本字段是一个具有焦点侦听器干扰我的代码的第三方编辑器。这里模拟为
selectAll()
。
目前分派的顺序是:在文本组件中输入字母,然后分派焦点侦听器。因为文本字段具有焦点,所以下一个字母被正确分派了。
我需要它将焦点设置在文本组件上,分派焦点侦听器,然后将按键事件传递给它。
public class JTableIssue extends JFrame {
public JTableIssue() {
JTable table = new JTable(new Object[][] {
{ "Apple", "Orange", "Strawberry" },
{ "Pineapple", "Orange", "Zergz" } }, new Object[] { "C1",
"C2", "C3" });
table.getColumn("C2").setCellEditor(new MyEditor());
add(new JScrollPane(table));
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JTableIssue().setVisible(true);
}
}
class MyEditor extends AbstractCellEditor implements TableCellEditor {
MyTextField textField = new MyTextField();
JPanel panel;
MyEditor() {
panel = new JPanel(new BorderLayout()){
// Trick: Pass all key typed to text field
@Override
protected boolean processKeyBinding(KeyStroke ks, KeyEvent e,
int condition, boolean pressed) {
if (ks.getKeyEventType() == KeyEvent.KEY_TYPED) {
textField.processKeyBinding(ks, e, condition, pressed);
}
return super.processKeyBinding(ks, e, condition, pressed);
}
};
textField.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
textField.selectAll();
}
});
panel.add(textField, BorderLayout.CENTER);
// Trick: Pass focus to text field when editor is added to table
panel.addAncestorListener(new AncestorListener() {
public void ancestorRemoved(AncestorEvent event) {
}
public void ancestorMoved(AncestorEvent event) {
}
public void ancestorAdded(AncestorEvent event) {
textField.requestFocus();
}
});
}
public Object getCellEditorValue() {
return textField.getText();
}
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
textField.setText(value.toString());
return panel;
}
}
class MyTextField extends JTextField {
// Trick: "public"
@Override
public boolean processKeyBinding(javax.swing.KeyStroke ks,
java.awt.event.KeyEvent e, int condition, boolean pressed) {
return super.processKeyBinding(ks, e, condition, pressed);
};
}