我有一个 JTextField
,我正在尝试向其中添加自动完成菜单。但我对如何处理焦点有疑问。
这是一个SSCCE
package test;
import java.awt.Point;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
public class SSCCE extends JFrame implements DocumentListener {
private AutocompletionDialog dialog;
public SSCCE() {
dialog = new AutocompletionDialog ();
JTextField textField = new JTextField(20);
textField.getDocument().addDocumentListener(this);
add(textField);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new SSCCE().setVisible(true);
}
});
}
public void insertUpdate(DocumentEvent e) {
Point p = this.getLocationOnScreen();
dialog.setLocation(p.x, p.y + 50);
dialog.setVisible(true);
}
public void removeUpdate(DocumentEvent e) { }
public void changedUpdate(DocumentEvent e) { }
private class AutocompletionDialog extends JDialog {
JList<String> list = new JList<>(
new String[] { "One", "Two", "Three" });
AutocompletionDialog() {
setSize(100, 100);
add(list);
}
}
}
当然,实际程序中有更多逻辑,但我遇到的问题是我想显示自动完成对话框/菜单,但仍然能够继续在文本字段中输入内容。同时,我还希望能够使用向上/向下箭头和 Enter 键以及鼠标导航菜单,以选择完成选项之一。
有人可以帮我解决这里应该如何进行吗?谢谢!
编辑:
感谢@camickr我使用 setFocusableWindowState
和 InputMap/ActionMap 进行了一些尝试,以始终将焦点保持在文本字段中,并手动控制选定的列表项。问题是,与列表具有适当焦点的情况相比,这样做时您会得到视觉上的差异。请参阅屏幕截图。
如果我不扰乱焦点,这就是它的样子(这就是我想要的)。
这就是我运行 setFocusableWindowState(false)
主要区别是所选列表项周围的突出显示边框(深蓝色),以及整个对话框周围的蓝色突出显示。然后标题栏也存在差异。
(不要介意渲染伪影,我正在使用旧的 NX 客户端连接到三年前的虚拟 Linux 安装)
编辑2:
我担心外观或操作系统决定了所选列表项的外观(例如突出显示的边框)。但事实证明,确实只是单元格渲染器进行了该调用。知道编写自己的单元格渲染器让我感觉好多了,现在我有了一个令我满意的解决方案。
这是我最终使用的代码:
private class CellRenderer extends DefaultListCellRenderer
{
@Override
public Component getListCellRendererComponent(
JList<?> jlist, Object value, int index,
boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(
jlist, value, index, isSelected, cellHasFocus);
if (isSelected) {
Border border = UIManager.getBorder(
"List.focusSelectedCellHighlightBorder");
if (border == null) {
border = UIManager.getBorder(
"List.focusCellHighlightBorder");
}
setBorder(border);
}
return this;
}
}
最佳答案
As I show the auto completion menu the focus is given to that dialog.
要防止焦点转到弹出窗口,您可以使用:
JDialog dialog = new JDialog(...);
dialog.setFocusableWindowState( false );
...
dialog.setVisible( true );
I also want to be able to navigate the menu with the up/down arrows and the enter key
然后您需要覆盖文本字段提供的默认操作。查看Key Bindings了解更多信息。
您还可以查看:button highlighting using keyboard keys我只是提供了一个实现操作的简单示例。
关于Java Swing : Controlling focus with textfield and autocompletion dialog/menu,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27582212/