2013-09-30 24 views
0

我有一個JCombobox上有一長串項目。 爲了快速訪問,您可以隨時鍵入所需的項目,並且組合框將您引導至列表中的項目。 問題是您需要輸入的速度非常高,如果您放慢鍵入項目,Combobox會將您引導至列表中的其他項目。JCombobox鍵盤輸入速度

我不知道在JCombobox中是否有一個屬性,或者是在忘記之前在內存中保留鍵盤輸入的時間稍長的方法。

在此先感謝。

+0

不是此搜索是基於雙擊系統屬性,從來沒有試圖改變這一屬性的JList或JComboBox中 – mKorbel

+0

但煥數組進行排序,然後將不會被這個問題引起的,項目數量巨大( cca 1k) – mKorbel

+0

>找到你的這個問題的解決方案,可能重複[點擊這裏](http://stackoverflow.com/questions/11983798/increase-performance-of-jcombobox-with-many-entries) – Sitansu

回答

0

默認的KeySelectionManager只是硬編碼1秒的延遲來組合鍵或開始一個新的搜索,所以你需要創建一個自定義的KeySelectionManager,允許你配置搜索延遲。看看BasicComboBoxUI類中的默認代碼。

以下或多或少是該代碼的副本。它有點複雜,因爲它沒有直接訪問JList。

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 
import javax.swing.plaf.basic.*; 
import javax.swing.text.*; 

public class ComboBoxKeySelection extends JPanel 
{ 
    JComboBox<String> comboBox; 

    public ComboBoxKeySelection() 
    { 
     String[] data = 
     { 
      " 1", " 2", " 3", " 4", 
      "a", "ab", "abc", "abcd", 
      "b1", "b2", "b3", "b4", "be", 
      "c", "d", "e", "f" 
     }; 

     comboBox = new JComboBox<String>(data); 
     add(comboBox); 

     UIManager.put("ComboBox.timeFactor", 3000); 
     comboBox.setKeySelectionManager(new MyKeySelectionManager(comboBox)); 
    } 


    static class MyKeySelectionManager implements JComboBox.KeySelectionManager 
    { 
     private JComboBox comboBox; 
     private JList listBox; 
     private boolean useComboBoxModel; 

     private int timeFactor; 
     private long lastTime; 
     private long time; 

     private String prefix = ""; 
     private String typedString = ""; 

     public MyKeySelectionManager(JComboBox comboBox) 
     { 
      this.comboBox = comboBox; 

      int uiTimeFactor = UIManager.getInt("ComboBox.timeFactor"); 
      timeFactor = (uiTimeFactor == 0) ? 1000 : uiTimeFactor; 

      // Get the JList used by the UI to hold the comboBox entries 

      Object child = comboBox.getAccessibleContext().getAccessibleChild(0); 

      if (child instanceof BasicComboPopup) 
      { 
       BasicComboPopup popup = (BasicComboPopup)child; 
       listBox = popup.getList(); 
       useComboBoxModel = false; 
      } 
      else 
      { 
       listBox = new JList(); 
       useComboBoxModel = true; 
      } 
     } 

     public int selectionForKey(char aKey, ComboBoxModel aModel) 
     { 
      // Not using the basic UI so build our own JList to search 

      if (useComboBoxModel) 
      { 
       listBox.setModel(aModel); 
      } 

      time = System.currentTimeMillis(); 
      boolean startingFromSelection = true; 
      int startIndex = comboBox.getSelectedIndex(); 

      if (time - lastTime < timeFactor) 
      { 
       typedString += aKey; 

       if((prefix.length() == 1) && (aKey == prefix.charAt(0))) 
       { 
        // Subsequent same key presses move the keyboard focus to the next 
        // object that starts with the same letter. 
        startIndex++; 
       } 
       else 
       { 
        prefix = typedString; 
       } 
      } 
      else 
      { 
       startIndex++; 
       typedString = "" + aKey; 
       prefix = typedString; 
      } 

      lastTime = time; 

      if (startIndex < 0 || startIndex >= aModel.getSize()) 
      { 
       startingFromSelection = false; 
       startIndex = 0; 
      } 

      int index = listBox.getNextMatch(prefix, startIndex, Position.Bias.Forward); 

      if (index < 0 && startingFromSelection) 
      { 
       // wrap 
       index = listBox.getNextMatch(prefix, 0, Position.Bias.Forward); 
      } 

      return index; 
     } 
    } 


    private static void createAndShowUI() 
    { 
     JFrame frame = new JFrame("ComboBoxKeySelection"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(new ComboBoxKeySelection()); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) 
    { 
     EventQueue.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       createAndShowUI(); 
      } 
     }); 
    } 
}