Приложение Windows с автозаполнением с использованием вкладки машинных файлов и каталогов Unix - PullRequest
0 голосов
/ 12 декабря 2011

Unix / Linux поддерживает автоматическое заполнение файлов и каталогов при нажатии клавиши «Tab».Мне нужно создать эту способность в моем приложении Windows.У меня есть текстовое поле для ввода пользователем имени файла, которое я хочу отреагировать на нажатие «вкладки», как это будет происходить, когда мы в консоли Unix:

  1. Если есть один вариант- Автозаполнение.
  2. Некоторые параметры - показать список параметров.
  3. Нет параметров - nada.

Для моего SSH-соединения с моей машиной Unix яиспользуйте API ch.ethz.ssh.

Есть ли способ сделать это?

1 Ответ

2 голосов
/ 12 декабря 2011

Сначала вы хотите иметь текстовое поле без циклической фокусировки и подавление табуляции:

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

Затем модель данных для файлов (здесь локальный каталог, но SSH также):

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

Затем нажата клавиша для обработки табуляции:

  • Поглотить событие.
  • Получить префикс в каретку для поиска имен файлов.
  • Если вам просто нужно ограничить уже найденные имена файлов, сделайте это, иначе физический поиск по ним.
  • Найдите самый длинный общий префикс в именах файлов. Покажите это.

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