我有一个JFrame
看起来像这样的:
它上面有两个JTextField
s,一个JComboBox
在它们之间,一个JPanel
在底部(你看不到)。
的特点之一JComboBox
是它可以被赋予一个自定义编辑器。这些实现了ComboBoxEditor
接口。在以下三种情况中的每一种情况下,GUI 看起来都完全相同,我希望它们的行为都完全相同:
- 我没有指定自定义编辑器,而是使用默认编辑器。
- 我创建了一个自定义编辑器,其编辑器组件是
JTextField
. - 我创建了一个自定义编辑器,其编辑器组件是 a ,上面
JPanel
带有 aJTextField
(使用 aBorderLayout
)。
当可编辑组合框的编辑器设置为默认值时,按下Tab会将焦点从顶部JTextField
移到 上的编辑区域JComboBox
,然后移到另一个JTextField
。如果我创建了一个自定义编辑器,其编辑器组件是 aJTextField
并且按照您的预期进行,同样的事情也会发生。
但是,如果我改为创建一个自定义编辑器,其编辑器组件是一个JPanel
带有JTextField
add
ed 的编辑器,那么焦点会额外停止。如果焦点在顶部JTextField
,则在移动到文本区域之前,按下Tab会将焦点移动到可编辑组合框右侧的小箭头。
为什么会这样?焦点永远不会移动到JPanel
框架的底部,那么为什么会影响组合框上的 Tab 键顺序呢 JPanel
?JTextField
下面是一个 S(-ish)SCCE,它有一个文本字段和所有三种类型的组合框:
import javax.swing.*;
import java.awt.event.*;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
public class ComboBoxTest extends JFrame
{
private JPanel layoutPanel;
private JTextField meaninglessTextField;
private JComboBox defaultEditorComboBox;
private JComboBox textFieldEditorComboBox;
private JComboBox panelEditorComboBox;
public ComboBoxTest()
{
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
layoutPanel = new JPanel();
layoutPanel.setLayout(new BoxLayout(layoutPanel, BoxLayout.Y_AXIS));
meaninglessTextField = new JTextField();
defaultEditorComboBox = new JComboBox(); // Just a default JComboBox.
defaultEditorComboBox.setEditable(true);
textFieldEditorComboBox = new JComboBox();
textFieldEditorComboBox.setEditable(true);
textFieldEditorComboBox.setEditor(new TextFieldEditor());
panelEditorComboBox = new JComboBox();
panelEditorComboBox.setEditable(true);
panelEditorComboBox.setEditor(new PanelEditor());
layoutPanel.add(Box.createRigidArea(new Dimension(500,0)));
layoutPanel.add(meaninglessTextField);
layoutPanel.add(defaultEditorComboBox);
layoutPanel.add(textFieldEditorComboBox);
layoutPanel.add(panelEditorComboBox);
Container contentPane = getContentPane();
contentPane.add(layoutPanel, BorderLayout.CENTER);
pack();
}
public static void main(String[] args)
{
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run()
{
new ComboBoxTest().setVisible(true);
}
});
}
private class PanelEditor extends JPanel implements ComboBoxEditor
{
public JTextField inputTextField = new JTextField();
public PanelEditor()
{
setLayout(new BorderLayout());
add(inputTextField, BorderLayout.CENTER);
}
@Override
public String getItem()
{
return inputTextField.getText();
}
@Override
public void setItem(Object newText)
{
if (newText != null) {
inputTextField.setText(newText.toString());
}
else {
inputTextField.setText("");
}
}
@Override
public Component getEditorComponent()
{
return this;
}
@Override
public void removeActionListener(ActionListener listener)
{
inputTextField.removeActionListener(listener);
}
@Override
public void addActionListener(ActionListener listener)
{
inputTextField.addActionListener(listener);
}
@Override
public void selectAll()
{
inputTextField.selectAll();
}
}
private class TextFieldEditor extends PanelEditor implements ComboBoxEditor
{
// The same, except that the editor component is now just the JTextField
// rather than the whole panel.
public TextFieldEditor()
{
}
@Override
public JTextField getEditorComponent()
{
return inputTextField;
}
}
}
注意:如果我想将 a 添加JLabel
到编辑器,此行为会成为问题。然后我必须在JPanel
那里放置标签和文本字段。