2012年11月13日 星期二

[ Java 代碼範本 ] Swing 之 JCombox - 模擬瀏覽器歷史查詢

Preface: 
在 Chrome 瀏覽器上面, 我們可以在輸入 URL 欄位的地方直接輸入查詢字串. 貼心的 Chrome 會自動幫我們帶出曾經被查詢的相關字串: 
 

那這樣的效果有辦法在 Swing 的 UI 上面呈現嗎? 其實 Chrome 上面顯示的相關查詢字串是來自後端服務器紀錄使用者的瀏覽紀錄而來, 但是在 Swing 開發的應用程式除非你自己架一個 Server 將每次使用者的查詢過程記錄起來, 否則能依據的就只有當前的查詢紀錄. 下面要介紹使用 JComboBox 來模擬這樣的效果, 將曾經查詢過的字串記下來, 並可以透過點擊 JComboBox 的下拉框帶出查詢紀錄. 

Sample code: 
首先我們設計的 UI 長相如下, 當按下按鈕 "Add" 時, 則代表進行查詢. 當 JComboBox 中的查詢字串未曾出現時, 則加入該字串到 JComboBox 的下拉選項中: 
 

首先為了要讓 JComboBox 可以編輯字串, 必須如下設定 JComboBox 的物件 jComboBox: 
  1. jComboBox.setEditable(true);  
當按鈕 "Add" 被點擊, 下面的 callback 會被執行: 
  1. private void jButtonActionPerformed(ActionEvent evt) {  
  2.     String qs = (String)jComboBox.getSelectedItem();  
  3.     System.out.printf("\t[Info] Query '%s'...\n", jComboBox.getSelectedItem());  
  4.     if(!queue.contains(qs))  
  5.     {  
  6.         queue.add(qs);  
  7.         updateComboBox(qs); // 更新 JComboBox 的選單  
  8.         JOptionPane.showConfirmDialog(this, String.format("Add '%s' into history...", qs), "Info", JOptionPane.CLOSED_OPTION, JOptionPane.INFORMATION_MESSAGE);  
  9.     }         
  10. }  
該 Callback 主要判斷查詢字串是否已經存在於物件 queue 中, 如果不存在則將該查詢字串加入 queue 並進行更新 JComboBox 選單的呼叫 "updateComboBox(qs)

這邊我們用類別 FSQueue 來記錄查詢字串, 
  1. private FSQueue queue = new FSQueue(10); // Keep 10 records. FIFO  
它是一個 Fixed size 的 Queue, 當 Queue 滿了後, FIFO 先進來的物件會被移出以便清出空間給加入的物件. 

當有新的物件加入, 下面方法會被呼叫以更新 JComboBox 的清單: 
  1. protected void updateComboBox(String qs)  
  2. {  
  3.     jComboBox.removeAllItems();  
  4.     for(String eqs:queue) jComboBox.addItem(eqs);  
  5.     jComboBox.setSelectedItem(qs);  
  6. }  
底下為完整代碼: 
  1. package swing.demo;  
  2.   
  3. import java.awt.BorderLayout;  
  4. import java.awt.event.ActionEvent;  
  5. import java.awt.event.ActionListener;  
  6.   
  7. import javax.swing.ComboBoxModel;  
  8. import javax.swing.DefaultComboBoxModel;  
  9. import javax.swing.JButton;  
  10. import javax.swing.JComboBox;  
  11. import javax.swing.JOptionPane;  
  12. import javax.swing.JPanel;  
  13. import javax.swing.SwingUtilities;  
  14. import javax.swing.WindowConstants;  
  15. import flib.util.FSQueue;  
  16.   
  17. public class JComboBoxDemo1 extends javax.swing.JFrame {  
  18.     private JPanel jPanelMain;  
  19.     private JComboBox jComboBox;  
  20.     private JButton jButton;  
  21.   
  22.     private FSQueue queue = new FSQueue(10); // Keep 10 records. FIFO  
  23.   
  24.     /** 
  25.     * Auto-generated main method to display this JFrame 
  26.     */  
  27.     public static void main(String[] args) {  
  28.         SwingUtilities.invokeLater(new Runnable() {  
  29.             public void run() {  
  30.                 JComboBoxDemo1 inst = new JComboBoxDemo1();  
  31.                 inst.setLocationRelativeTo(null);  
  32.                 inst.setVisible(true);  
  33.             }  
  34.         });  
  35.     }  
  36.       
  37.     public JComboBoxDemo1() {  
  38.         super();  
  39.         initGUI();  
  40.     }  
  41.       
  42.     private void initGUI() {  
  43.         try {  
  44.             setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);  
  45.             this.setTitle("JComboBox \u6b77\u53f2\u7d00\u9304");  
  46.             {  
  47.                 jPanelMain = new JPanel();  
  48.                 getContentPane().add(jPanelMain, BorderLayout.CENTER);  
  49.                 jPanelMain.setBackground(new java.awt.Color(0,255,0));  
  50.                 jPanelMain.setLayout(null);  
  51.                 jPanelMain.setPreferredSize(new java.awt.Dimension(48462));  
  52.                 {  
  53.                     ComboBoxModel jComboBoxModel =   
  54.                             new DefaultComboBoxModel(  
  55.                                     new String[] {});  
  56.                     jComboBox = new JComboBox();  
  57.                     jPanelMain.add(jComboBox);  
  58.                     jComboBox.setModel(jComboBoxModel);  
  59.                     jComboBox.setBounds(121238824);  
  60.                     jComboBox.setEditable(true);  
  61.                 }  
  62.                 {  
  63.                     jButton = new JButton();  
  64.                     jPanelMain.add(jButton);  
  65.                     jButton.setText("Add");  
  66.                     jButton.setBounds(412136124);  
  67.                     jButton.addActionListener(new ActionListener() {  
  68.                         public void actionPerformed(ActionEvent evt) {  
  69.                             jButtonActionPerformed(evt);  
  70.                         }  
  71.                     });  
  72.                 }  
  73.             }  
  74.             pack();  
  75.             this.setSize(500100);  
  76.         } catch (Exception e) {  
  77.             //add your error handling code here  
  78.             e.printStackTrace();  
  79.         }  
  80.     }  
  81.       
  82.     protected void updateComboBox(String qs)  
  83.     {  
  84.         jComboBox.removeAllItems();  
  85.         for(String eqs:queue) jComboBox.addItem(eqs);  
  86.         jComboBox.setSelectedItem(qs);  
  87.     }  
  88.       
  89.     private void jButtonActionPerformed(ActionEvent evt) {  
  90.         String qs = (String)jComboBox.getSelectedItem();  
  91.         System.out.printf("\t[Info] Query '%s'...\n", jComboBox.getSelectedItem());  
  92.         if(!queue.contains(qs))  
  93.         {  
  94.             queue.add(qs);  
  95.             updateComboBox(qs); // 更新 JComboBox 的選單  
  96.             JOptionPane.showConfirmDialog(this, String.format("Add '%s' into history...", qs), "Info", JOptionPane.CLOSED_OPTION, JOptionPane.INFORMATION_MESSAGE);  
  97.         }         
  98.     }  
  99. }  
Execution: 
執行代碼後再出現 UI 的 輸入區鍵入 "aaa" 並點擊按鈕 "Add". 此時因為 "aaa" 未出現在歷史查詢, 會有 popup 提示加入該字串到歷史紀錄: 
 

執行代碼後再出現 UI 的 輸入區鍵入 "bbb" 並點擊按鈕 "Add". 同樣因為 "bbb" 未出現在歷史查詢, 會有 popup 提示加入該字串到歷史紀錄: 
 

此時點擊 JComboBox 的下拉按鈕, 選項清單會有 "aaa" 與 "bbb": 
 

選擇 "aaa" 並點擊按鈕 "Add". 此時因為 "aaa" 已經出現在歷史清單, 故不會有 popup! 

Supplement: 
The Java Tutorial > How to Use Combo Boxes

沒有留言:

張貼留言

[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...