Java Swing:使用文本字段和自动完成对话框/菜单控制焦点

时间:2014-12-20 16:38:44

标签: java swing autocomplete jtextfield jdialog

我有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一起玩了一下,始终将焦点保持在文本字段中,并手动控制所选列表项。问题是,与列表具有适当焦点的情况相比,这样做时会产生视觉差异。看屏幕截图。

如果我不关注焦点(这就是我想要的),这就是它的样子。

dialog with proper focus

如果我运行setFocusableWindowState(false)

,这就是它的样子

dialog with no focus

主要区别在于所选列表项周围的高亮边框(深蓝色),以及整个对话框周围的蓝色高光。然后还有标题栏中的差异。

(不要介意渲染工件,我使用旧的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;
    }
}

1 个答案:

答案 0 :(得分:2)

  

当我显示自动完成菜单时,焦点将放在该对话框上。

为防止焦点转到弹出窗口,您可以使用:

JDialog dialog = new JDialog(...);
dialog.setFocusableWindowState( false );
...
dialog.setVisible( true );
  

我还希望能够使用向上/向下箭头和回车键

导航菜单

然后,您需要覆盖文本字段提供的默认操作。查看Key Bindings了解详情。

您还可以查看:button highlighting using keyboard keys我刚刚提供了一个实施操作的简单示例。