Windows应用程序与自动完成使用选项卡的unix机器文件和目录



Unix/Linux支持按"tab"键自动完成文件和目录。我需要在我的windows应用程序中创建这种能力。我有一个用于用户输入文件名的文本字段,我想响应"tab"键,就像我们在unix控制台中所做的那样:

  1. 如果有一个选项-自动完成。
  2. 一些选项-显示选项列表

对于到unix机器的SSH连接,我使用ch.ethz.ssh API。

有办法吗?

首先,你想要一个没有焦点循环和制表符抑制的文本字段:

jTextField1.setFocusCycleRoot(true);
jTextField1.setFocusTraversalKeysEnabled(false);       
然后是文件的数据模型(这里是本地目录,SSH也一样):
private File dir = new File("C:/Work");
private String typedPrefix = null;
private List<String> filesWithPrefix = new ArrayList<>();

然后按下TAB键处理:

  • 消耗事件
  • 获取插入符号前的前缀,用于搜索文件名。
  • 如果你只是需要限制已经找到的文件名,那么就这样做,否则就物理搜索它们。
  • 查找文件名中最长的通用前缀。显示。

    private void jTextField1KeyPressed(java.awt.event.KeyEvent evt) {
    System.out.println("KeyPressed " + evt);
    if (evt.getKeyCode() == KeyEvent.VK_TAB) {
        evt.consume();
        int caretPos = jTextField1.getCaretPosition();
        try {
            final String newPrefix = jTextField1.getText(0, caretPos);
            System.out.println("newPrefix: " + newPrefix);
            if (!newPrefix.isEmpty()) {
                if (typedPrefix == null || !newPrefix.startsWith(typedPrefix)) {
                    // Must physically reload possible values:
                    String[] fileNames = dir.list(new FilenameFilter() {
                        @Override
                        public boolean accept(File dir, String name) {
                            return name.startsWith(newPrefix);
                        }
                    });
                    filesWithPrefix.clear();
                    Collections.addAll(filesWithPrefix, fileNames);
                    typedPrefix = newPrefix;
                } else {
                    // Can reduce prior selection:
                    for (ListIterator<String> it = filesWithPrefix.listIterator(); it.hasNext(); ) {
                        String fileName = it.next();
                        if (!fileName.startsWith(newPrefix)) {
                            it.remove();
                        }
                    }
                    typedPrefix = newPrefix;
                }
                System.out.println("filesWithPrefix: " +filesWithPrefix);
                if (!filesWithPrefix.isEmpty()) {
                    // Find longest common prefix:
                    String longestCommonPrefix = null;
                    for (String fileName : filesWithPrefix) {
                        if (longestCommonPrefix == null) {
                            longestCommonPrefix = fileName;
                        } else {
                            while (!fileName.startsWith(longestCommonPrefix)) {
                                longestCommonPrefix = longestCommonPrefix.substring(0, longestCommonPrefix.length() - 1);
                            }
                        }
                    }
                    if (longestCommonPrefix.length() > typedPrefix.length()) {
                        jTextField1.setText(longestCommonPrefix);
                        jTextField1.setCaretPosition(longestCommonPrefix.length());
                        typedPrefix = longestCommonPrefix;
                    }
                    if (filesWithPrefix.size() > 1) {
                        // Show popup:
                        ;;;
                    } else if (filesWithPrefix.size() == 1) {
                        // File selected:
                        System.beep();
                    }
                }
            }
        } catch (BadLocationException ex) {
            Logger.getLogger(TabsJFrame.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    }
    

缺少的是显示不明确的文件名。弹出式菜单会很好,不是吗?

弹出:

                    // Show popup:
                    JPopupMenu popup = new JPopupMenu();
                    for (String fileName : filesWithPrefix) {
                        popup.add(new AbstractAction(fileName) {
                             @Override
                            public void actionPerformed(ActionEvent e) {
                                jTextField1.setText(e.getActionCommand());
                            }
                        });
                    }
                    Point pt = jTextField1.getCaret().getMagicCaretPosition();
                    popup.show(jTextField1, pt.x, pt.y + 5);

相关内容

  • 没有找到相关文章

最新更新