自动完成JTextField和箭头键

Pau*_*gas 9 java swing text jtextfield

我试图建立一个javax.swing.JTextFieldjavax.swing.JList用于自动完成像谷歌.

  • 当写一个单词时,Google显示几个匹配

    • 按下  ▼  我可以选择一些匹配使用  ▲   ,并  ▼  
    • 可以用  ◀ 和编辑我的输入  ▶  .
    • 当我按下   Enter         键搜索框中的内容.
    • 当按下Esc该框切换到原始输入时.

我的应用是关于圣经,我想在研究圣经时寻找一个特定的词.我已经看过Java2sAutoTextField,但箭头键没有这种特殊的行为.

geo*_*e_h 9

这需要一个自定义编码组件.绝对是一个扩展JTextField的类,在该类中你有一个包含你的JList的JPopupMenu.您必须将JPopupMenu放在文本字段下面,使其看起来像1个组件.

您的下一个技巧是在键入时进行过滤.我通常使用Java6 TableRowSorter和一个JTable来做到这一点,我用它来预先填充数据.您需要在JTextField上使用一些更改侦听器并拦截键入的每个键并获取您的数据.

  1. 按键
  2. 在DB(或某些数据存储中执行查询以获取类似条目)中执行查询
  3. 使用这些entires填充JTable
  4. 使用基于JTextField条目的正则表达式设置RowFilter以筛选检索到的数据
  5. 使用关键侦听器管理您的操作

编辑

我掀起了一个示例摇摆应用程序,以显示我说的内容.这是一个复制/粘贴示例,应该可以正常工作(需要JDK 1.6+).我基本上得到了你想要的东西,我把评论放在我告诉你填补空白的地方......例如,Escape键事件已被消耗,你可以随心所欲地做任何事情.

initTableModel()方法只是用数据初始化表模型.通常,您希望使用来自数据库或其他内容的数据动态填充表模型.可以调整很多,但这只是为了清酒;)所以这应该是一个足够好的例子,你可以修改你完成你的目标.不仅如此,你必须付我$$$ :)

package test.text.googleclone;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.regex.PatternSyntaxException;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.RowFilter;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;

public class SearchAutoFillTest {

private JFrame frame = null;
private JTextField searchField = null;
private JPopupMenu popup = null;

private JTable searchTable = null;
private TableRowSorter<DefaultTableModel> rowSorter = null;
private DefaultTableModel searchTableModel = null;

public SearchAutoFillTest() {
    searchTableModel = new DefaultTableModel();
    initTableModel();

    rowSorter = new TableRowSorter<DefaultTableModel>(searchTableModel);
    searchTable = new JTable(searchTableModel);
    searchTable.setRowSorter(rowSorter);
    searchTable.setFillsViewportHeight(true);
    searchTable.getColumnModel().setColumnSelectionAllowed(false);
    searchTable.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
    searchTable.getTableHeader().setReorderingAllowed(false);
    searchTable.setPreferredSize(new Dimension(775, 100));
    searchTable.setGridColor(Color.WHITE);

    searchField = new JTextField();
    searchField.getDocument().addDocumentListener(new DocumentListener() {
        @Override
        public void changedUpdate(DocumentEvent e) {
            showPopup(e);
        }

        @Override
        public void insertUpdate(DocumentEvent e) {
            showPopup(e);
        }

        @Override
        public void removeUpdate(DocumentEvent e) {
            showPopup(e);
        }
    });

    searchField.addKeyListener(new KeyListener() {
        @Override
        public void keyTyped(KeyEvent e) {

        }

        @Override
        public void keyReleased(KeyEvent e) {
            int code = e.getKeyCode();
            switch(code)
            {
                case KeyEvent.VK_UP:
                {
                    cycleTableSelectionUp();
                    break;
                }

                case KeyEvent.VK_DOWN:
                {
                    cycleTableSelectionDown();
                    break;
                }

                case KeyEvent.VK_LEFT:
                {
                    //Do whatever you want here
                    break;
                }

                case KeyEvent.VK_RIGHT:
                {
                    //Do whatever you want here
                    break;
                }
            }
        }

        @Override
        public void keyPressed(KeyEvent e) {

        }
    });

    KeyStroke keyStroke = KeyStroke.getKeyStroke("ESCAPE");
    searchField.getInputMap().put(keyStroke, "ESCAPE");
    searchField.getActionMap().put("ESCAPE", new AbstractAction() {
        @Override
        public void actionPerformed(ActionEvent e) {
            //Do what you wish here with the escape key.
        }
    });

    popup = new JPopupMenu();
    popup.add(searchTable);
    popup.setVisible(false);
    popup.setBorder(BorderFactory.createEmptyBorder());

    JPanel searchPanel = new JPanel(new BorderLayout(5, 5));
    searchPanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
    searchPanel.add(searchField, BorderLayout.CENTER);

    frame = new JFrame();
    frame.setLayout(new BorderLayout(5, 5));
    frame.add(searchPanel, BorderLayout.NORTH);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(800, 500);
    center(frame);
    frame.setVisible(true);
}

private final void newFilter() {
    RowFilter<DefaultTableModel, Object> rf = null;

    try {
        rf = RowFilter.regexFilter(getFilterText(), 0);
    }
    catch(PatternSyntaxException e) {
        return;
    }

    rowSorter.setRowFilter(rf);
}

private final String getFilterText() {
    String orig = searchField.getText();
    return "("+orig.toLowerCase()+")|("+orig.toUpperCase()+")";
}

private void showPopup(DocumentEvent e) {
    if(e.getDocument().getLength() > 0) {
        if(!popup.isVisible()) { 
            Rectangle r = searchField.getBounds();
            popup.show(searchField, (r.x-4), (r.y+16));
            popup.setVisible(true);
        }

        newFilter();
        searchField.grabFocus();

    }
    else {
        popup.setVisible(false);
    }
}

private void cycleTableSelectionUp() {
    ListSelectionModel selModel = searchTable.getSelectionModel();
    int index0 = selModel.getMinSelectionIndex();
    if(index0 > 0) {
        selModel.setSelectionInterval(index0-1, index0-1);
    }
}

private void cycleTableSelectionDown() {
    ListSelectionModel selModel = searchTable.getSelectionModel();
    int index0 = selModel.getMinSelectionIndex();
    if(index0 == -1) {
        selModel.setSelectionInterval(0, 0);
    }
    else if(index0 > -1) {
        selModel.setSelectionInterval(index0+1, index0+1);
    }
}

private void initTableModel() {
    String[] columns = new String[] {"A"};
    String[][] data = new String[][]
    {
        new String[] {"a"},
        new String[] {"aa"},
        new String[] {"aaab"},
        new String[] {"aaabb"},
        new String[] {"aaabbbz"},
        new String[] {"b"},
        new String[] {"bb"},
        new String[] {"bbb"},
        new String[] {"bbbbbbb"},
        new String[] {"bbbbbbbeee"},
        new String[] {"bbbbbbbeeexxx"},
        new String[] {"ccc"},
        new String[] {"cccc"},
        new String[] {"ccccc"},
        new String[] {"cccccaaaa"},
        new String[] {"ccccccaaaa"},
    };

    searchTableModel.setDataVector(data, columns);
}

private void center(Window w) {
    int screenWidth  = Toolkit.getDefaultToolkit().getScreenSize().width;
    int screenHeight = Toolkit.getDefaultToolkit().getScreenSize().height;

    int windowWidth = w.getWidth();
    int windowHeight = w.getHeight();

    if (windowHeight > screenHeight) {
        return;
    }

    if (windowWidth > screenWidth) {
        return;
    }

    int x = (screenWidth - windowWidth) / 2;
    int y = (screenHeight - windowHeight) / 2;

    w.setLocation(x, y);
}

public static void main(String ... args) {
    new SearchAutoFillTest();
}
}
Run Code Online (Sandbox Code Playgroud)