Windows application with Auto-complete using tab of unix machine files and directories

杀马特。学长 韩版系。学妹 提交于 2019-12-02 10:47:28

First you want to have a text field without focus cycling, and tab suppression:

jTextField1.setFocusCycleRoot(true);
jTextField1.setFocusTraversalKeysEnabled(false);       

Then a data model for the files (here local directory, but SSH is likewise):

private File dir = new File("C:/Work");
private String typedPrefix = null;
private List<String> filesWithPrefix = new ArrayList<>();

Then a key pressed handling for the TAB:

  • Consume the event.
  • Get the prefix upto the caret for searching file names.
  • If you merely need to restrict already found file names, so do, otherwise physical search them.
  • Look for the longest common prefix in the file names. Display that.

    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);
        }
    }
    }
    

What is missing is the display of the ambiguous file names. Popup menu would be nice, wouldn't it?

Popup:

                    // 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);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!