我有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);
}
}
}
当然在真实程序中它有更多的逻辑,但我遇到的问题是我想显示自动完成对话框/菜单,但仍然能够继续输入文本领域。同时,我还希望能够使用向上/向下箭头和回车键以及鼠标导航菜单,以选择其中一个完成选项。
有人可以帮我解释一下我应该怎么办?谢谢!
修改
感谢@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;
}
}
答案 0 :(得分:2)
当我显示自动完成菜单时,焦点将放在该对话框上。
为防止焦点转到弹出窗口,您可以使用:
JDialog dialog = new JDialog(...);
dialog.setFocusableWindowState( false );
...
dialog.setVisible( true );
我还希望能够使用向上/向下箭头和回车键
导航菜单
然后,您需要覆盖文本字段提供的默认操作。查看Key Bindings了解详情。
您还可以查看:button highlighting using keyboard keys我刚刚提供了一个实施操作的简单示例。