2013-01-06 37 views
24

我想創建一個自動建議文本框,它將在每個鍵釋放事件中查詢數據庫。 這部分很簡單,但我想給它很好的視覺效果。類似於我們在Facebook等網站中看到的自動提示文本框。使用下拉列表在Java中創建自動填充文本框

如何製作這樣的界面?

一個天真的想法是將一個JList放置在文本框的正下方,並將其設置爲可見,並在查找結果中將其顯示出來。

任何更好的主意或標準的做法?

+0

[看看這個現有的答案](http://stackoverflow.com/questions/1861921/auto-complete-textbox-in-java-swing?rq=1) – atomman

+0

它沒有下拉!這可以做到。問題在於如何根據結果的數量來顯示可變大小的下拉菜單。 – jairaj

+0

@jairaj無論用JTextField都可以實現什麼,可以很容易地轉換成JComboBox。您只需將該JTextField設置爲JCombobox的ComboBoxEditor,並使JComboBox可編輯。順便說一句,我會看看SwingX已經有一個相當不錯的autocomlete組件(看看谷歌) –

回答

39

@ syb0rg的答案比較容易,因爲它使用了第三方庫。

但是我使用的替代方法:

它使用稱爲AutoSuggestor的自定義類,它接受一個JTextField,其Window話要檢查,背景顏色和文本顏色,並建議聚焦色類型的單詞的ArrayList<String>以及不透明的價值。通過傳遞JTextField參考DocumentListener將被添加,這將執行檢查什麼單詞是鍵入和是否顯示建議,如果是的話顯示什麼建議的工作。當鍵入一個單詞時,DocumentListener將觸發wordTyped(String wordTyped)方法,並輸入當前單詞或(至少有多少單詞已輸入),在wordTyped(..)中將對照那些在AutoSuggestor類中的單詞字典其中是的String這個基本ArrayList可以即時被設置爲在下面的例子中看出:

enter image description here

(現在你將不得不使用鼠標點擊你想成爲自動補全的詞,或使用向下橫向建議和textfield and ENTER使用下移鍵時,選擇建議。我還沒有實現UP尚):

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.GridLayout; 
import java.awt.Window; 
import java.awt.event.ActionEvent; 
import java.awt.event.KeyEvent; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.util.ArrayList; 
import javax.swing.AbstractAction; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 
import javax.swing.JWindow; 
import javax.swing.KeyStroke; 
import javax.swing.SwingUtilities; 
import javax.swing.border.LineBorder; 
import javax.swing.event.DocumentEvent; 
import javax.swing.event.DocumentListener; 

/** 
* @author David 
*/ 
public class Test { 

    public Test() { 

     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 


     JTextField f = new JTextField(10); 

     AutoSuggestor autoSuggestor = new AutoSuggestor(f, frame, null, Color.WHITE.brighter(), Color.BLUE, Color.RED, 0.75f) { 
      @Override 
      boolean wordTyped(String typedWord) { 

       //create list for dictionary this in your case might be done via calling a method which queries db and returns results as arraylist 
       ArrayList<String> words = new ArrayList<>(); 
       words.add("hello"); 
       words.add("heritage"); 
       words.add("happiness"); 
       words.add("goodbye"); 
       words.add("cruel"); 
       words.add("car"); 
       words.add("war"); 
       words.add("will"); 
       words.add("world"); 
       words.add("wall"); 


       setDictionary(words); 
       //addToDictionary("bye");//adds a single word 

       return super.wordTyped(typedWord);//now call super to check for any matches against newest dictionary 
      } 
     }; 

     JPanel p = new JPanel(); 

     p.add(f); 

     frame.add(p); 

     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new Test(); 
      } 
     }); 
    } 
} 

class AutoSuggestor { 

    private final JTextField textField; 
    private final Window container; 
    private JPanel suggestionsPanel; 
    private JWindow autoSuggestionPopUpWindow; 
    private String typedWord; 
    private final ArrayList<String> dictionary = new ArrayList<>(); 
    private int currentIndexOfSpace, tW, tH; 
    private DocumentListener documentListener = new DocumentListener() { 
     @Override 
     public void insertUpdate(DocumentEvent de) { 
      checkForAndShowSuggestions(); 
     } 

     @Override 
     public void removeUpdate(DocumentEvent de) { 
      checkForAndShowSuggestions(); 
     } 

     @Override 
     public void changedUpdate(DocumentEvent de) { 
      checkForAndShowSuggestions(); 
     } 
    }; 
    private final Color suggestionsTextColor; 
    private final Color suggestionFocusedColor; 

    public AutoSuggestor(JTextField textField, Window mainWindow, ArrayList<String> words, Color popUpBackground, Color textColor, Color suggestionFocusedColor, float opacity) { 
     this.textField = textField; 
     this.suggestionsTextColor = textColor; 
     this.container = mainWindow; 
     this.suggestionFocusedColor = suggestionFocusedColor; 
     this.textField.getDocument().addDocumentListener(documentListener); 

     setDictionary(words); 

     typedWord = ""; 
     currentIndexOfSpace = 0; 
     tW = 0; 
     tH = 0; 

     autoSuggestionPopUpWindow = new JWindow(mainWindow); 
     autoSuggestionPopUpWindow.setOpacity(opacity); 

     suggestionsPanel = new JPanel(); 
     suggestionsPanel.setLayout(new GridLayout(0, 1)); 
     suggestionsPanel.setBackground(popUpBackground); 

     addKeyBindingToRequestFocusInPopUpWindow(); 
    } 

    private void addKeyBindingToRequestFocusInPopUpWindow() { 
     textField.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "Down released"); 
     textField.getActionMap().put("Down released", new AbstractAction() { 
      @Override 
      public void actionPerformed(ActionEvent ae) {//focuses the first label on popwindow 
       for (int i = 0; i < suggestionsPanel.getComponentCount(); i++) { 
        if (suggestionsPanel.getComponent(i) instanceof SuggestionLabel) { 
         ((SuggestionLabel) suggestionsPanel.getComponent(i)).setFocused(true); 
         autoSuggestionPopUpWindow.toFront(); 
         autoSuggestionPopUpWindow.requestFocusInWindow(); 
         suggestionsPanel.requestFocusInWindow(); 
         suggestionsPanel.getComponent(i).requestFocusInWindow(); 
         break; 
        } 
       } 
      } 
     }); 
     suggestionsPanel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "Down released"); 
     suggestionsPanel.getActionMap().put("Down released", new AbstractAction() { 
      int lastFocusableIndex = 0; 

      @Override 
      public void actionPerformed(ActionEvent ae) {//allows scrolling of labels in pop window (I know very hacky for now :)) 

       ArrayList<SuggestionLabel> sls = getAddedSuggestionLabels(); 
       int max = sls.size(); 

       if (max > 1) {//more than 1 suggestion 
        for (int i = 0; i < max; i++) { 
         SuggestionLabel sl = sls.get(i); 
         if (sl.isFocused()) { 
          if (lastFocusableIndex == max - 1) { 
           lastFocusableIndex = 0; 
           sl.setFocused(false); 
           autoSuggestionPopUpWindow.setVisible(false); 
           setFocusToTextField(); 
           checkForAndShowSuggestions();//fire method as if document listener change occured and fired it 

          } else { 
           sl.setFocused(false); 
           lastFocusableIndex = i; 
          } 
         } else if (lastFocusableIndex <= i) { 
          if (i < max) { 
           sl.setFocused(true); 
           autoSuggestionPopUpWindow.toFront(); 
           autoSuggestionPopUpWindow.requestFocusInWindow(); 
           suggestionsPanel.requestFocusInWindow(); 
           suggestionsPanel.getComponent(i).requestFocusInWindow(); 
           lastFocusableIndex = i; 
           break; 
          } 
         } 
        } 
       } else {//only a single suggestion was given 
        autoSuggestionPopUpWindow.setVisible(false); 
        setFocusToTextField(); 
        checkForAndShowSuggestions();//fire method as if document listener change occured and fired it 
       } 
      } 
     }); 
    } 

    private void setFocusToTextField() { 
     container.toFront(); 
     container.requestFocusInWindow(); 
     textField.requestFocusInWindow(); 
    } 

    public ArrayList<SuggestionLabel> getAddedSuggestionLabels() { 
     ArrayList<SuggestionLabel> sls = new ArrayList<>(); 
     for (int i = 0; i < suggestionsPanel.getComponentCount(); i++) { 
      if (suggestionsPanel.getComponent(i) instanceof SuggestionLabel) { 
       SuggestionLabel sl = (SuggestionLabel) suggestionsPanel.getComponent(i); 
       sls.add(sl); 
      } 
     } 
     return sls; 
    } 

    private void checkForAndShowSuggestions() { 
     typedWord = getCurrentlyTypedWord(); 

     suggestionsPanel.removeAll();//remove previos words/jlabels that were added 

     //used to calcualte size of JWindow as new Jlabels are added 
     tW = 0; 
     tH = 0; 

     boolean added = wordTyped(typedWord); 

     if (!added) { 
      if (autoSuggestionPopUpWindow.isVisible()) { 
       autoSuggestionPopUpWindow.setVisible(false); 
      } 
     } else { 
      showPopUpWindow(); 
      setFocusToTextField(); 
     } 
    } 

    protected void addWordToSuggestions(String word) { 
     SuggestionLabel suggestionLabel = new SuggestionLabel(word, suggestionFocusedColor, suggestionsTextColor, this); 

     calculatePopUpWindowSize(suggestionLabel); 

     suggestionsPanel.add(suggestionLabel); 
    } 

    public String getCurrentlyTypedWord() {//get newest word after last white spaceif any or the first word if no white spaces 
     String text = textField.getText(); 
     String wordBeingTyped = ""; 
     if (text.contains(" ")) { 
      int tmp = text.lastIndexOf(" "); 
      if (tmp >= currentIndexOfSpace) { 
       currentIndexOfSpace = tmp; 
       wordBeingTyped = text.substring(text.lastIndexOf(" ")); 
      } 
     } else { 
      wordBeingTyped = text; 
     } 
     return wordBeingTyped.trim(); 
    } 

    private void calculatePopUpWindowSize(JLabel label) { 
     //so we can size the JWindow correctly 
     if (tW < label.getPreferredSize().width) { 
      tW = label.getPreferredSize().width; 
     } 
     tH += label.getPreferredSize().height; 
    } 

    private void showPopUpWindow() { 
     autoSuggestionPopUpWindow.getContentPane().add(suggestionsPanel); 
     autoSuggestionPopUpWindow.setMinimumSize(new Dimension(textField.getWidth(), 30)); 
     autoSuggestionPopUpWindow.setSize(tW, tH); 
     autoSuggestionPopUpWindow.setVisible(true); 

     int windowX = 0; 
     int windowY = 0; 

     windowX = container.getX() + textField.getX() + 5; 
     if (suggestionsPanel.getHeight() > autoSuggestionPopUpWindow.getMinimumSize().height) { 
      windowY = container.getY() + textField.getY() + textField.getHeight() + autoSuggestionPopUpWindow.getMinimumSize().height; 
     } else { 
      windowY = container.getY() + textField.getY() + textField.getHeight() + autoSuggestionPopUpWindow.getHeight(); 
     } 

     autoSuggestionPopUpWindow.setLocation(windowX, windowY); 
     autoSuggestionPopUpWindow.setMinimumSize(new Dimension(textField.getWidth(), 30)); 
     autoSuggestionPopUpWindow.revalidate(); 
     autoSuggestionPopUpWindow.repaint(); 

    } 

    public void setDictionary(ArrayList<String> words) { 
     dictionary.clear(); 
     if (words == null) { 
      return;//so we can call constructor with null value for dictionary without exception thrown 
     } 
     for (String word : words) { 
      dictionary.add(word); 
     } 
    } 

    public JWindow getAutoSuggestionPopUpWindow() { 
     return autoSuggestionPopUpWindow; 
    } 

    public Window getContainer() { 
     return container; 
    } 

    public JTextField getTextField() { 
     return textField; 
    } 

    public void addToDictionary(String word) { 
     dictionary.add(word); 
    } 

    boolean wordTyped(String typedWord) { 

     if (typedWord.isEmpty()) { 
      return false; 
     } 
     //System.out.println("Typed word: " + typedWord); 

     boolean suggestionAdded = false; 

     for (String word : dictionary) {//get words in the dictionary which we added 
      boolean fullymatches = true; 
      for (int i = 0; i < typedWord.length(); i++) {//each string in the word 
       if (!typedWord.toLowerCase().startsWith(String.valueOf(word.toLowerCase().charAt(i)), i)) {//check for match 
        fullymatches = false; 
        break; 
       } 
      } 
      if (fullymatches) { 
       addWordToSuggestions(word); 
       suggestionAdded = true; 
      } 
     } 
     return suggestionAdded; 
    } 
} 

class SuggestionLabel extends JLabel { 

    private boolean focused = false; 
    private final JWindow autoSuggestionsPopUpWindow; 
    private final JTextField textField; 
    private final AutoSuggestor autoSuggestor; 
    private Color suggestionsTextColor, suggestionBorderColor; 

    public SuggestionLabel(String string, final Color borderColor, Color suggestionsTextColor, AutoSuggestor autoSuggestor) { 
     super(string); 

     this.suggestionsTextColor = suggestionsTextColor; 
     this.autoSuggestor = autoSuggestor; 
     this.textField = autoSuggestor.getTextField(); 
     this.suggestionBorderColor = borderColor; 
     this.autoSuggestionsPopUpWindow = autoSuggestor.getAutoSuggestionPopUpWindow(); 

     initComponent(); 
    } 

    private void initComponent() { 
     setFocusable(true); 
     setForeground(suggestionsTextColor); 

     addMouseListener(new MouseAdapter() { 
      @Override 
      public void mouseClicked(MouseEvent me) { 
       super.mouseClicked(me); 

       replaceWithSuggestedText(); 

       autoSuggestionsPopUpWindow.setVisible(false); 
      } 
     }); 

     getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, true), "Enter released"); 
     getActionMap().put("Enter released", new AbstractAction() { 
      @Override 
      public void actionPerformed(ActionEvent ae) { 
       replaceWithSuggestedText(); 
       autoSuggestionsPopUpWindow.setVisible(false); 
      } 
     }); 
    } 

    public void setFocused(boolean focused) { 
     if (focused) { 
      setBorder(new LineBorder(suggestionBorderColor)); 
     } else { 
      setBorder(null); 
     } 
     repaint(); 
     this.focused = focused; 
    } 

    public boolean isFocused() { 
     return focused; 
    } 

    private void replaceWithSuggestedText() { 
     String suggestedWord = getText(); 
     String text = textField.getText(); 
     String typedWord = autoSuggestor.getCurrentlyTypedWord(); 
     String t = text.substring(0, text.lastIndexOf(typedWord)); 
     String tmp = t + text.substring(text.lastIndexOf(typedWord)).replace(typedWord, suggestedWord); 
     textField.setText(tmp + " "); 
    } 
} 

目前的情況是唯一可能需要的補充IMO是:

  • UP重點traversablity物品彈出自動建議盒子內,所以我們可以向上發展。

如果有任何扭結知道我會看看我能做些什麼。但似乎運行良好(觸摸木材)。

+1

好的一個!但是當我輸入的重點從文本字段丟失。我必須再次點擊文本字段才能重新開始輸入。所以,對於我輸入的每個字符,我都必須強調文本字段和類型。你有沒有遇到這個問題?如果是的話,你有修好嗎? – arunram

+0

@arunram同樣的事情發生在我身上。該代碼在Windows 7上運行得很完美,但沒有在Machintosh OS X Yosemite(10.10.2)上運行。我仍然試圖解決這個問題,但我不是專家,所以這可能需要很長時間。沒有承諾,但我會盡我所能。 – panoet

+0

我最喜歡這個解決方案。其他人更優雅,但這個更容易破解和學習 –

25

一個很簡單的方法就是使用自動完成的GlazedList實現。起牀和跑步非常容易。你可以找到它here

可以安裝自動完成上一個JComboBox,只有一行的釉面代碼,就像這樣:

JComboBox comboBox = new JComboBox(); 
Object[] elements = new Object[] {"Cat", "Dog", "Lion", "Mouse"}; 
AutoCompleteSupport.install(comboBox, GlazedLists.eventListOf(elements)); 

而且SwingX支持自動完成,可能會更容易比GlazedList使用。你用SwingX寫的全部是AutoCompleteDecorator.decorate(comboBox);

+3

「你用SwingX編寫的所有代碼都是AutoCompleteDecorator.decorate(comboBox);」很好的回答!!!爲什麼我只在4天后才發現這個問題? – Blocked

+0

我得到這個錯誤代碼:'必須從Swing Event Dispatch Thread'訪問'AutoCompleteSupport'。 –

+0

我找不到jar文件GlazedLists.eventListOf可以幫我找到一個jar文件。 – heshjse

2

要使用TextAutoCompleter類,你需要下載一個jar文件AutoCompleter.jar並將其添加到您的項目的庫文件夾,這裏是鏈接下載:http://download1689.mediafire.com/4grrthscpsug/7pwzgefiomu392o/AutoCompleter.jar -Nawin

//在主類寫下面的代碼

package autocomplete; 

import com.mxrck.autocompleter.TextAutoCompleter; 
import java.sql.SQLException; 
import javax.swing.JFrame; 
import javax.swing.JTextField; 


public class AutoComplete { 
    JFrame f=new JFrame(); 
    JTextField t1; 
AutoComplete() throws ClassNotFoundException, SQLException{ 

    f.setSize(500,500); 
    f.setLocation(500,100); 
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    f.setLayout(null); 
    f.setVisible(true); 


    t1=new JTextField(); 
    t1.setBounds(50,80,200,20); 
    f.add(t1); 


    TextAutoCompleter complete=new TextAutoCompleter(t1); 
    DBConn conn=new DBConn(); 
     conn.connection(); 
     conn.retrieve(); 
    while(conn.rs.next()){ 

     complete.addItem(conn.rs.getString("number")); 
    } 


} 


    public static void main(String[] args) throws ClassNotFoundException, 
    SQLException{   

     new AutoComplete(); 
    } 

} 


//Create seperate class for database connection and write the following code 


package autocomplete; 

import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.sql.Statement; 


public class DBConn { 

    Connection con; ResultSet rs;PreparedStatement stat; 

public void connection() throws ClassNotFoundException, SQLException{ 
    String url="jdbc:mysql://localhost:3306/"; 
    String driver="com.mysql.jdbc.Driver"; 
    String db="demo"; 
    String username="root"; 
    String password="root"; 
    stat =null; 

     Class.forName(driver); 
     con=(Connection)DriverManager.getConnection 
     (url+db,username,password);    
     System.out.println("Connecttion SuccessFul"); 
} 

public void retrieve() throws SQLException{ 

    Statement stmt=con.createStatement(); 
    String query="select number from phone"; 
    rs = stmt.executeQuery(query); 

    System.out.println("retrieve succesfully"); 

} 

}

+0

khawatiwada感謝您的建議。我正在網上衝浪,偶然發現了這一點。我想在一個HTTP服務器(如WAMP)中使用它,我將通過RESTFul API調用我的字符串。你清楚的例子中只有一個問題:我如何使用在文本字段中輸入的字符串作爲serach參數?上面的例子對我來說真的不太清楚。謝謝 – Maximum86

1

我想自動完成對我的AVR彙編IDE的編輯器,以便I wrote an implementation的作品就像在Eclipse(CTRL-SPACE激活自動完成,滴,倒升帶滾動條,光標鍵+鼠標導航)。它沒有外部依賴關係,只是一個類。它應該適用於所有JTextComponent子類;您可以在src/test文件夾中找到一個使用示例。

0

將此行添加到第一個答案的private void addKeyBindingToRequestFocusInPopUpWindow()以實現UP鍵。他的回答很完美。

//here I have to do my code for up key 
    //--------------------------------------------------------------------- 
    //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
    //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
    textField.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "Up released"); 
    textField.getActionMap().put("Up released", new AbstractAction() { 
     @Override 
     public void actionPerformed(ActionEvent ae) {//focuses the first label on popwindow 
      for (int i = suggestionsPanel.getComponentCount()-1; i >=0; i--) { 
       if (suggestionsPanel.getComponent(i) instanceof SuggestionLabel) { 
        ((SuggestionLabel) suggestionsPanel.getComponent(i)).setFocused(true); 
        autoSuggestionPopUpWindow.toFront(); 
        autoSuggestionPopUpWindow.requestFocusInWindow(); 
        suggestionsPanel.requestFocusInWindow(); 
        suggestionsPanel.getComponent(i).requestFocusInWindow(); 
        break; 
       } 
      } 
     } 
    }); 

    suggestionsPanel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "Up released"); 
    suggestionsPanel.getActionMap().put("Up released", new AbstractAction() { 
     //######int lastFocusableIndex = 0; 
     int lastFocusableIndex = 0; 
     //lastFocusableIndex=lastFocusableIndex___; 
     @Override 
     public void actionPerformed(ActionEvent ae) {//allows scrolling of labels in pop window (I know very hacky for now :)) 

      ArrayList<SuggestionLabel> sls = getAddedSuggestionLabels(); 
      int max = sls.size(); 
      lastFocusableIndex=lastFocusableIndex___; 

      System.out.println("UP UP UP UP");//***// 
      System.out.println("max = "+String.valueOf(max));//***// 
      System.out.println("lastFocusableIndex = "+String.valueOf(lastFocusableIndex));//***// 
      System.out.println("UP UP UP UP");//***// 

      if (max > 1) {//more than 1 suggestion 
       for (int i = max-1; i >=0; i--) { 
        SuggestionLabel sl = sls.get(i); 
        if (sl.isFocused()) { 
         if (lastFocusableIndex == 0) { 
          lastFocusableIndex = max - 1; 
          lastFocusableIndex___=lastFocusableIndex; 
          sl.setFocused(false); 
          autoSuggestionPopUpWindow.setVisible(false); 
          setFocusToTextField(); 
          checkForAndShowSuggestions();//fire method as if document listener change occured and fired it 

         } else { 
          sl.setFocused(false); 
          lastFocusableIndex = i; 
          lastFocusableIndex___=lastFocusableIndex; 
         } 
        } else if (lastFocusableIndex > i) { 
         if (i < max) { 
          sl.setFocused(true); 
          autoSuggestionPopUpWindow.toFront(); 
          autoSuggestionPopUpWindow.requestFocusInWindow(); 
          suggestionsPanel.requestFocusInWindow(); 
          suggestionsPanel.getComponent(i).requestFocusInWindow(); 
          lastFocusableIndex = i; 
          lastFocusableIndex___=lastFocusableIndex; 
          break; 
         } 
        } 
       } 
      } else {//only a single suggestion was given 
       autoSuggestionPopUpWindow.setVisible(false); 
       setFocusToTextField(); 
       checkForAndShowSuggestions();//fire method as if document listener change occured and fired it 
      } 
     } 
    }); 
0

,我在一個項目上使用的工作計算策略是把一個JTextField上的JComboBox的頂部,使底層組合框打開,你使用的文檔偵聽器鍵入到JTextField中。您可能需要一個自定義組合框模型,以便更有效地更改項目,因爲默認模型我認爲只允許一次添加一個項目,這可能會影響性能。打開組合框我認爲有一種方法來顯示它,如果你得到它的用戶界面。當我嘗試在打開項目時嘗試更改項目時,遇到了幾個滾動錯誤,因此您可能需要關閉它,更改項目並重新顯示。對於鍵盤的東西,您可以捕獲JTextField中的鍵盤按鍵,並適當地調用JComboBox。