JList常見用法總結

 今天從《java核心編程》中學習了JList 的用法,寫下自己的感受,以免時間久了又忘記了。
        JList從含義上看是一個列表,有點和JComboBox相似。其實不然,JComboBox的內容只能用一列顯示出來,而JList的內容可以多列顯示,我想這就是JList存在的意義。
        首先是JList的構造,沒什麼特別的,給他一個對象數組就可以了,代碼說明一切:
JList常見用法總結String[] words= { "quick", "brown", "hungry", "wild"};
JList常見用法總結JList wordList = new JList(words);
        然後就是JList的多列顯示,使用setLayoutOrientation(參數)方法來實現,共有3個參數,默認值是JList.VERTICAL,只用一列來顯示,但不會自動滾動,需要添加滾動面板才能出現滾動條。
setVisibleRowCount(n);方法可以設置最多顯示多少行(若沒有添加滾動面板,此設置無效,所有內容均會顯示)。
另外兩個參數是JList.VERTICAL_WRAP和JList.HORIZONTAL_WRAP,其含義分別是“在保證行數不超過setVisibleRowCount(n)的情況下,縱向或橫向排列元素”。此時滾動面板無效,因爲行數永遠不可能超標,因此滾動面板也永遠不會出現。比如最大顯示行數爲4,總共有5個元素,顯示結果如下:
JList常見用法總結
        接下來就是事件的處理,與其他控件不同,他處理的不是Action事件,而是ListSelectionEvent事件,監聽器爲ListSelectionListener。在這個事件處理過程中,又將鼠標的操作分爲2種狀態:
1.按下鼠標不鬆手,在各個元素間拖動;
2.鬆開鼠標。
也就是說,當你按下鼠標後,會觸發一個事件,拖動到另一個控件,又觸發一個事件,繼續拖動則繼續觸發事件,最後鬆手,觸發一個事件。那麼,你如何區分這2種情況呢?ListSelectionEvent提供了一個方法getValueIsAdjusting(),如果該方法返回true,則代表情況1;反之代表情況2。同時請注意,JList控件不提供鼠標雙擊元素的處理事件,若要處理鼠標雙擊的情況,則應該添加鼠標監聽器,代碼如下:
JList常見用法總結public void mouseClicked(MouseEvent evt)
JList常見用法總結JList常見用法總結...{
JList常見用法總結   if (evt.getClickCount() == 2)
JList常見用法總結JList常見用法總結   ...{
JList常見用法總結       JList source = (JList) evt.getSource();
JList常見用法總結       Object[] selection = source.getSelectedValues();
JList常見用法總結       doAction(selection);
JList常見用法總結    }
JList常見用法總結}
        JList還有一個很有趣的特性,就是你根本沒必要把元素存入一個數組,只要能臨時把元素計算出來就行。具體實現方法就是繼承AbstractListModel類,實現其中的2個方法即可,代碼如下:
JList常見用法總結class WordListModel extends AbstractListModel
JList常見用法總結JList常見用法總結...{
JList常見用法總結JList常見用法總結   
JList常見用法總結JList常見用法總結   public WordListModel(int n) ...{ length = n; }
JList常見用法總結
JList常見用法總結   public int getSize()
JList常見用法總結JList常見用法總結   ...{
JList常見用法總結      return (int) Math.pow(LAST - FIRST + 1, length);
JList常見用法總結    }
JList常見用法總結
JList常見用法總結   public Object getElementAt(int n)
JList常見用法總結JList常見用法總結   ...{
JList常見用法總結       StringBuilder r = new StringBuilder();;
JList常見用法總結      for (int i = 0; i < length; i++)
JList常見用法總結JList常見用法總結      ...{
JList常見用法總結         char c = (char)(FIRST + n % (LAST - FIRST + 1));
JList常見用法總結          r.insert(0, c);
JList常見用法總結          n = n / (LAST - FIRST + 1);
JList常見用法總結       }
JList常見用法總結      return r;
JList常見用法總結    }
JList常見用法總結
JList常見用法總結   private int length;
JList常見用法總結   public static final char FIRST = 'a';
JList常見用法總結   public static final char LAST = 'z';
JList常見用法總結}
        接下來就是元素的插入和刪除了,這個看似簡單的功能,實現起來可不是一件容易的事情。最天真的想法:我用一個數組構造JList,那麼我只要將數組中的元素增加或減少,那麼JList的內容自然會增加或減少。這絕對是個錯誤的認識,對數組內容的修改不會影響到JList。正確的做法是,用一個特別的類來構造JList,也就是DefaultListModel類,然後對這個類的內容添加或者減少,那麼JList會很快的做出響應。爲什麼這個類會這麼神奇呢?查看他的源代碼得知,他繼承自AbstractListModel類,內部用一個Vector來存儲數據。在它的添加元素方法中,他調用了父類的fireIntervalAdded方法,同理,在他的刪除元素方法中,他調用了父類的fireIntervalRemoved方法,因此可以將JList的內容刷。
   最後就是內部元素的繪製了。在JList中,內部顯示的每一個元素叫做一個Cell。如果我想讓內部元素的顯示方式更完美一些,比如居中顯示,比如每一個Cell字體顏色不一樣,那麼我們就要藉助JList的setCellRenderer方法來實現。該方法接受一個實現了ListCellRenderer接口的參數,而該接口只有一個方法getListCellRendererComponent,但是,該方法的實現是比較簡單的,他只需要構造一個Component對象並返回這個對象,這個對象就是一個Cell。因此,真正的難點在於,如何修改這個Component的內部顯示方式,從而使得他可以滿足一個Cell的顯示方式。一般來講,我們都是用一個JPanel作爲繪製Cell的對象,因爲在JPanel上顯示文字和圖像都是很方便的。最後說一個小技巧,我們實現一個類,從JPanel繼承而來,同時又實現了ListCellRenderer接口,那麼我們只用實現這一個類就可以了,到時候把自己返回,呵呵,真的好方便哦。下面我們來看一下具體的代碼:
JList常見用法總結 class FontCellRenderer extends JPanel implements ListCellRenderer
JList常見用法總結JList常見用法總結 ...{
JList常見用法總結    public Component getListCellRendererComponent(JList list, Object value, int index,
JList常見用法總結       boolean isSelected, boolean cellHasFocus)
JList常見用法總結JList常見用法總結    ...{
JList常見用法總結        text = (String)value;
JList常見用法總結        background = isSelected ? list.getSelectionBackground() : list.getBackground();
JList常見用法總結        foreground = isSelected ? list.getSelectionForeground() : list.getForeground();
JList常見用法總結       return this;
JList常見用法總結     }
JList常見用法總結
JList常見用法總結    public void paintComponent(Graphics g)
JList常見用法總結JList常見用法總結    ...{
JList常見用法總結        g.setColor(background);
JList常見用法總結        g.fillRect(0, 0, getWidth(), getHeight()); //設置背景色
JList常見用法總結        g.setColor(foreground);
JList常見用法總結        g.drawString(text, 5, 15);   //在制定位置繪製文本
JList常見用法總結     }
JList常見用法總結
JList常見用法總結    public Dimension getPreferredSize()
JList常見用法總結JList常見用法總結    ...{
JList常見用法總結       return new Dimension(30, 20);   //Cell的尺寸
JList常見用法總結     }
JList常見用法總結
JList常見用法總結    private String text;
JList常見用法總結    private Color background;
JList常見用法總結    private Color foreground;
JList常見用法總結 }
JList常見用法總結
    我們來簡單分析一下上面的代碼。我們定義了一個類,繼承自JPanel並實現了指定接口。在這個類裏面有3個私有變量,分別存放Cell的內容,Cell的前景色和背景色。因爲Cell的繪製完全由程序員來實現,因此這些內容都是必須的。之後就是接口中規定的getListCellRendererComponent方法,這個方法其實很簡單,就是對三個變量進行賦值並返回自己。其中前景色和背景色又分爲2中情況,就是選中時和未選中時,這點需要注意。接下來我們有實現了2個方法,其中PaintComponent負責Cell的繪製,GetPreferedSize負責設置Cell的尺寸。對於尺寸有一點需要注意,上述代碼給的是一個固定尺寸。如果尺寸不固定有變化,那麼最終會選擇最大的那個尺寸作爲所有Cell的尺寸。如果你想在繪製Cell的時候加入什麼花樣,那麼儘管在PaintComponent中施展你的才華吧,上述代碼只提供了在指定位置繪製文本,算是拋磚引玉了。這裏也有一點需要注意,那就是JPanel本身提供的“居中”,“設置背景色”,“設置前景色”,等方法一律失效,所有的功能一律要使用JAVA 2D來實現,算是一點小小的難度。
=======================
paintComponent定義在JComponent中,這個類是所有非窗口Swing組件的超類,只要窗口需要重新繪圖,事件處理器就會通告組件,從而引發執行所有組件的paintComponent方法。一定不要自己調用paintComponent方法。--摘自《Java核心技術》
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章