Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>First you want to have a text field without focus cycling, and tab suppression:</p> <pre><code>jTextField1.setFocusCycleRoot(true); jTextField1.setFocusTraversalKeysEnabled(false); </code></pre> <p>Then a data model for the files (here local directory, but SSH is likewise):</p> <pre><code>private File dir = new File("C:/Work"); private String typedPrefix = null; private List&lt;String&gt; filesWithPrefix = new ArrayList&lt;&gt;(); </code></pre> <p>Then a key pressed handling for the TAB:</p> <ul> <li>Consume the event.</li> <li>Get the prefix upto the caret for searching file names.</li> <li>If you merely need to restrict already found file names, so do, otherwise physical search them.</li> <li><p>Look for the longest common prefix in the file names. Display that.</p> <pre><code>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&lt;String&gt; 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() &gt; typedPrefix.length()) { jTextField1.setText(longestCommonPrefix); jTextField1.setCaretPosition(longestCommonPrefix.length()); typedPrefix = longestCommonPrefix; } if (filesWithPrefix.size() &gt; 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); } } } </code></pre></li> </ul> <p>What is missing is the display of the ambiguous file names. Popup menu would be nice, wouldn't it?</p> <p>Popup:</p> <pre><code> // 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); </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload