Swing JComboBox的詳細使用

JComboBox
7-4:JComboBox的使用:
類層次結構圖:
   java.lang.Object
    --java.awt.Component
     --java.awt.Container
      --javax.swing.JComponent
       --javax.swing.JComboBox 
   構造函數:
    JComboBox():建立一個新的JComboBox組件。
    JComboBox(ComboBoxModel aModel):用ListModel建立一個新的JComboBox組件。
    JComboBox(Object[] items):利用Array對象建立一個新的JComboBox組件。
    JComboBox(Vector items):利用Vector對象建立一個新的JComboBox組件。 
7-4-1:建立一般的JComboBox:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Vector;


public class JComboBox1{
public static void main(String[] args){
JFrame f=new JFrame("JComboBox1");
Container contentPane=f.getContentPane();
contentPane.setLayout(new GridLayout(1,2));
String[] s = {"美國","日本","大陸","英國","法國","意大利","澳洲","韓國"};
Vector v=new Vector();
v.addElement("Nokia 8850");
v.addElement("Nokia 8250");
v.addElement("Motorola v8088");
v.addElement("Motorola v3850");
v.addElement("Panasonic 8850");
    v.addElement("其它");
    
    JComboBox combo1=new JComboBox(s);
    combo1.addItem("中國");//利用JComboBox類所提供的addItem()方法,加入一個項目到此JComboBox中。
    combo1.setBorder(BorderFactory.createTitledBorder("你最喜歡到哪個國家玩呢?"));
    JComboBox combo2=new JComboBox(v);
    combo2.setBorder(BorderFactory.createTitledBorder("你最喜歡哪一種手機呢?"));   
    contentPane.add(combo1);
    contentPane.add(combo2);
    f.pack();
    f.show();
    f.addWindowListener(new WindowAdapter(){
    public void windowClosing(WindowEvent e){
    System.exit(0); 
    }
    });
}
}
7-4-2:利用ComboModel構造JComboBox:
    如同JList一般,在JComboBox中也有一個構造函數是利用某種Model來構造。如下所示:
      JComboBox(COmboBoxModel aModel)
   ComboBoxModel是一個interface,裏面定義了兩個方法,分別是setSelectedItem()與getSelectedItem().這兩個方法目的是讓用
戶選取某個項目後,可正確地顯示出用戶所選取的項目。下面是這兩個方法的詳細定義:
ComboBoxModel interface定義的方法:
   Object    getSelectedItem():返回所選取的項目值。
   Void      setSelectedItem(Object anItem):設置所選取的項目值.


與JList不同的是,JComboBox是利用ComboBoxModel,而不是ListModel.不過ComboBoxModel interface是繼承ListModel interface
,因此若我們要利用ComboBoxModel來構造JComboBox,除了要實作ComboBoxModel的兩個方法外,還必須實作ListModel的所定義的4個
方法,這樣的做法可說相當麻煩。
   在介紹JList時我們曾經提到AbstractListModel這個抽象類。這個抽象類實作了ListModel interface中的addListDataListener
()、removeListDataListener()這兩個方法。因此若我們繼承AbstractListModel,則可少掉實作這兩個方法,只需要實作
getElementAt()、getSize()、setSelectedItem()與getSelectedItem()這4個方法。這樣的作法就顯得比較簡單一點.


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


public class JComboBox2{
String[] s= {"美國","日本","大陸","英國","法國","意大利","澳洲","韓國"};
public JComboBox2(){
    JFrame f=new JFrame("JComboBox2"); 
    Container contentPane=f.getContentPane();
    
    ComboBoxModel mode=new UserDefineComboBoxModel();
    JComboBox combo=new JComboBox(mode);
    combo.setBorder(BorderFactory.createTitledBorder("你最喜歡到哪個國家去玩?"));
    contentPane.add(combo);
    f.pack();
    f.show();
    f.addWindowListener(new WindowAdapter(){
    public void windowClosing(WindowEvent e){
    System.exit(0); 
    }
    });   

public static void main(String[] args){
new JComboBox2();
}


class UserDefineComboBoxModel extends AbstractListModel implements ComboBoxModel{
String item=null;
public Object getElementAt(int index){
   return s[index++]; 
}
     //由於繼承AbstractListModel抽象類。因此我們分別在程序中實作了getElementAt()與getSize()方法。
public int getSize(){
    return s.length; 
}
     //由於我們實現了ComboBoxModel interface.因此我們必須在程序中實作setSelectedItem()與getSelectedItem()方法.
public void setSelectedItem(Object anItem){
      item=(String)anItem; 
     }
     public Object getSelectedItem(){
        return item; 
     }
}
}
   當程序要show出JComboBox時,系統會先自動調用getSize()方法,看看這個JComboBox長度有多少,然後再調用getElementAt()
方法,將String Array s中的值填入JComboBox中。當用戶選擇項目時,系統會調用getSelectedItem()方法,返回所選取的項目,並
利用setSelectedItem()方法,將選取項目放在JComboBox最前端。
   getElementAt()方法中的“index”參數,系統會自動由0計算,不過要自己作累加的操作,如程序中:
    return s[index++];
如同JList一般,java對於JComboBox也提供了另一個類,DefaultComboBoxModel實體類。此類繼承了AbstractListModel抽象類,也
實作了ComboBoxModel interface.因此你不需要再實作getSize()、getElementAt()、setSelectedItem()與getSelectedItem()方法。
利用DefaultComboBoxModel這個類我們可以很方便地做到動態更改JComboBox的項目值。當你沒有必要自己定義特殊的ComboBoxModel
時,使用DefaultComboBoxModel就顯得非常的方便,我們來看下面的例子:


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


public class JComboBox3{
   String[] s = {"美國","日本","大陸","英國","法國","意大利","澳洲","韓國"};
   public JComboBox3(){
      JFrame f=new JFrame("JComboBox3"); 
      Container contentPane=f.getContentPane();
      
      ComboBoxModel mode=new AModel();
      JComboBox combo=new JComboBox(mode);
      combo.setBorder(BorderFactory.createTitledBorder("您最喜歡到哪個國家玩呢?"));
      contentPane.add(combo);
      f.pack();
      f.show();
      f.addWindowListener(new WindowAdapter(){
    public void windowClosing(WindowEvent e){
    System.exit(0); 
    }
      });   
   }
   public static void main(String[] args){
      new JComboBox3(); 
   } 
   class AModel extends DefaultComboBoxModel{
   AModel(){
   for (int i=0;i<s.length;i++)
   addElement(s[i]);
   }
   }
}
    1.由於AModel繼承DefaultComboBoxModel實體類,由AModel可得到一個ComboBoxModel實體對象。
    2.我們使AModel繼承DefaultComboBoxModel實體類,因此就不需要再實作getElementAt()、getSize()、setSelectedItem()與
      getSelectedItem()這4個方法,直接將所要的項目用addElement()方法加入即可。系統會自動將所加入的項目放進一個Vector
      中,並在輸出JComboBox時自動調用getSize()與getElementAt()方法。
7-4-3:建立有圖像的JComboBox:
    在上一節中我們利用ListCellRenderer interface在JList中加入Icon圖像,而要在JComboBox中加入圖像的方法也是一樣的。
我們必須實作ListCellRenderer interface所定義的方法getListCellRendererComponent.以下爲這個方法的定義:
要先了解ListCellRenderer interface.我們必須由這個interface所定義的方法,將圖像畫在JComboBox中的每個項目。
ListCellRenderer interface裏只定義了一個方法,那就是getListCellRendererComponent,不過這個參數有點多,我們把它列出來
看看:
public Component getListCellRendererComponent(JList list,
                                              Object value,
                                              int index,
                                              boolean isSelected,
                                              boolean cellHasFocus)
list:即所要畫上的圖像的JComboBox組件。
value:JComboBox項目值,如JComboBox.getModel().getElementAt(index)所返回的值。
index:爲JComboBox項目的索引值,由0開始。
isSelected與cellHasFocus:判斷JComboBox中的項目是否有被選取或是有焦點置入。
上面這4個參數會在你設置JComboBox的繪圖樣式(setCellRenderer())時自動的由JComboBox組件提供,你只要關心怎麼控制
getListCellRendererComponent()方法中的4個參數,而無需擔心怎麼參數傳入。
   要在JList中加入Icon圖像的技巧就是將JComboBox中的每一個項目當作是JLabel,因爲JLabel在使用文字與圖像上非常的方便,要設置JComboBox的圖像,
必須使用setRenderer(ListCellRenderer cellRenderer){注:我們在JList中畫上圖像是利用JList所提供的setCellRenderer(ListCellRenderer 
cellRenderer)方法,讀者請小心}這個方法。我們來看下面這個範例,你就能明白了!


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


public class JComboBox4{
String[] s={"西瓜","蘋果","草莓","香蕉","葡萄"}; 
public JComboBox4(){
JFrame f=new JFrame("JComboBox");
Container contentPane=f.getContentPane();


JComboBox combo=new JComboBox(s);
combo.setBorder(BorderFactory.createTitledBorder("你最喜歡吃哪些水果?"));
combo.setRenderer(new ACellRenderer());
combo.setMaximumRowCount(3);


contentPane.add(combo);
      f.pack();
      f.show();
      f.addWindowListener(new WindowAdapter(){
    public void windowClosing(WindowEvent e){
    System.exit(0); 
    }
      });     
}
public static void main(String[] args){
new JComboBox4();
}
}
class ACellRenderer extends JLabel implements ListCellRenderer{
ACellRenderer(){
   setOpaque(true); 
}
public Component getListCellRendererComponent(JList list,
                                              Object value,
                                              int index,
                                              boolean isSelected,
                                              boolean cellHasFocus){
    if (value!=null){
      setText(value.toString());
      setIcon(new ImageIcon(".\\icons\\fruit"+(index+1)+".jpg"));
    } 
    if (isSelected){
       setBackground(list.getSelectionBackground());
       setForeground(list.getSelectionForeground()); 
    }else{
       setBackground(list.getBackground()); 
       setForeground(list.getForeground());
    }                                    
    return this;       
    }                                              
}
    各們讀者在運行這個程序時會發現,即使JComboBox的選項中有圖標,但在選後圖標卻不會顯示在顯示列中,原因是在上面程序中
我們以String Array s建立JComboBox:
      JComboBox combo=new JComboBox(s);
      String Array s裏面放的只是水果名稱,而並沒有圖標。當我們使用setRenderer()方法來JComboBox時,只會繪製JComboBox的
選項部份,而最後顯示在JComboBox上的值還是以String Array s爲依據。因此JComboBox顯示列就只會顯示文字而已,而不會顯示出
圖形。要解決這個問題,我們必須改變JComboBox所傳入的參數內容,也就是將原來的String Array s更改成具有圖形的數據項。在
此我們是利用JComboBox(Object[] items)來建立有圖像的JComboBox,我們所傳進去的Object Array不應該只有文字,而必須連圖標一
並傳入。我們修改上個範例修改如下:


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


public class JComboBox5
{
    String[] s = {"西瓜","蘋果","草莓","香蕉","葡萄"};
    ImageIcon[] icons = new ImageIcon[5];;
    
    public JComboBox5()
    {
        JFrame f = new JFrame("JComboBox");
        Container contentPane = f.getContentPane();
        ItemObj[] obj = new ItemObj[5];
        
        for(int i=0; i < 5; i++)
        {
            icons[i] = new ImageIcon(".\\icons\\fruit"+(i+1)+".jpg");
            obj[i] = new ItemObj(s[i],icons[i]);
        }
        
        JComboBox combo = new JComboBox(obj);//利用ItemObj Array obj當作是JComboBox的參數傳入,構造出JComboBox.
        combo.setBorder(BorderFactory.createTitledBorder("您喜歡吃哪些水果?"));
        combo.setRenderer(new ACellRenderer());
        combo.setMaximumRowCount(3);
        
        contentPane.add(combo);
        f.pack();
        f.show();
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                    System.exit(0);
            }
        });
    }
    
    public static void main(String args[])
    {
        new JComboBox5();
    }
}


class ItemObj
{
    String name;
    ImageIcon icon;
    
    public ItemObj(String name, ImageIcon icon){
        this.name = name;
        this.icon = icon;
    }
}
    
class ACellRenderer extends JLabel implements ListCellRenderer
{
    ACellRenderer()
    {
        setOpaque(true);
    }
    
    public Component getListCellRendererComponent(JList list,
                                                  Object value,
                                                  int index,
                                                  boolean isSelected,
                                                  boolean cellHasFocus)
    {
        if (value != null)
        {
            setText(((ItemObj)value).name);
            setIcon(((ItemObj)value).icon);
        }


        if (isSelected) {
            setBackground(list.getSelectionBackground());
            setForeground(list.getSelectionForeground());
        }
        else {
            setBackground(list.getBackground());
            setForeground(list.getForeground());
        }


        return this;
    }    
}


   你可以發現,第一欄顯示有圖標顯示出來了。當然你也可以利用ComboBoxModel方式來構造出有圖標的JComboBox.我們來看下面
的例子:


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


public class JComboBox6{
String[] s={"西瓜","蘋果","草莓","香蕉","葡萄"};
ImageIcon[] icons=new ImageIcon[5];
public JComboBox6(){
    JFrame f=new JFrame("JComboBox"); 
    Container contentPane=f.getContentPane();
        for(int i=0; i < 5; i++)
        {
            icons[i] = new ImageIcon(".\\icons\\fruit"+(i+1)+".jpg");
        }
        ComboBoxModel mode=new AModel();
        JComboBox combo=new JComboBox(mode);
        combo.setBorder(BorderFactory.createTitledBorder("您喜歡吃哪些水果?"));
        combo.setRenderer(new ACellRenderer());
        combo.setMaximumRowCount(3);
        
        contentPane.add(combo);
        f.pack();
        f.show();
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                    System.exit(0);
            }
        });

public static void main(String[] args){
new JComboBox6();
}
/*我們用JComboBox(ComboBoxModel aModel)來構造圖標的JComboBox,因此我們在程序中編寫一個繼承DefaultComboBoxModel的
ComboBoxModel.
*/
class AModel extends DefaultComboBoxModel{
AModel(){
   for (int i=0;i<s.length;i++){
      ItemObj obj=new ItemObj(s[i],icons[i]); 
      addElement(obj);
   } 
}
}
}
class ItemObj
{
    String name;
    ImageIcon icon;
    
    public ItemObj(String name, ImageIcon icon){
        this.name = name;
        this.icon = icon;
    }
}
    
class ACellRenderer extends JLabel implements ListCellRenderer
{
    ACellRenderer()
    {
        setOpaque(true);
    }
    
    public Component getListCellRendererComponent(JList list,
                                                  Object value,
                                                  int index,
                                                  boolean isSelected,
                                                  boolean cellHasFocus)
    {
        if (value != null)
        {
            setText(((ItemObj)value).name);
            setIcon(((ItemObj)value).icon);
        }


        if (isSelected) {
            setBackground(list.getSelectionBackground());
            setForeground(list.getSelectionForeground());
        }
        else {
            setBackground(list.getBackground());
            setForeground(list.getForeground());
        }


        return this;
    }    
}


   我們用JComboBox(ComboBoxModel aModel)來構造圖標的JComboBox,因此我們在程序中編寫一個繼承DefaultComboBoxModel的
ComboBoxModel.


7-4-4:建立可自行輸入的JComboBox:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


public class JComboBox7
{
    String[] fontsize = {"12","14","16","18","20","22","24","26","28"};
    String defaultMessage = "請選擇或直接輸入文字大小!";
    
    public JComboBox7()
    {
        JFrame f = new JFrame("JComboBox");
        Container contentPane = f.getContentPane();
        
        JComboBox combo = new JComboBox(fontsize);
        combo.setBorder(BorderFactory.createTitledBorder("請選擇你要的文字大小"));
        combo.setEditable(true);//將JComboBox設成是可編輯的.
        ComboBoxEditor editor = combo.getEditor();//getEditor()方法返回ComboBoxEditor對象,如果你查看手冊,你就會發
         //現ComboBoxEditor是個接口(interface),因此你可以自行實作這個接口,製作自己想要的ComboBoxEditor組件。但通常
         //我們不需要這麼做,因爲默認的ComboBoxEditor是使用JTextField,這已經足夠應付大部份的情況了。
        
        //configureEditor()方法會初始化JComboBox的顯示項目。例如例子中一開始就出現:"請選擇或直接輸入文字大小!"這個
        //字符串。
        combo.configureEditor(editor, defaultMessage);
        
        contentPane.add(combo);
        f.pack();
        f.show();
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                    System.exit(0);
            }
        });
    }
    
    public static void main(String args[])
    {
        new JComboBox7();
    }
}




7-4-5:JComboBox的事件處理:
    JComboBox的事件處理亦可分爲兩種,一種是取得用戶選取的項目;另一種是用戶在JComboBox上自行輸入完畢後按下[Enter]鍵,
運作相對應的工作。對於第一種事件的處理,我們使用ItemListener.對於第二種事件的處理,我們使用ActionListener.
    這個範例用戶可以選取所要的字號,字號的變化會呈現在JLabel上,並可讓用戶自行輸入字體的大小。當用戶按下[Enter]鍵後
,若用戶輸入的值不在選項上時,此輸入值會增加至JComboBox中,並將輸入字體的大小顯示在JLabel上。


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


public class JComboBox8 implements ItemListener,ActionListener{
String[] fontsize={"12","14","16","18","20","22","24","26","28"};
String defaultMessage="請選擇或直接輸入文字大小!";
Font font=null;
JComboBox combo=null;
JLabel label=null;


public JComboBox8(){
JFrame f=new JFrame("JComboBox"); 
Container contentPane=f.getContentPane();
contentPane.setLayout(new GridLayout(2,1));
label=new JLabel("Swing",JLabel.CENTER);
font=new Font("SansSerif",Font.PLAIN,12);
label.setFont(font);


combo=new JComboBox(fontsize);
combo.setBorder(BorderFactory.createTitledBorder("請選擇你要的文字大小:"));
combo.setEditable(true);
ComboBoxEditor editor=combo.getEditor();
combo.configureEditor(editor,defaultMessage);
combo.addItemListener(this);0
combo.addActionListener(this);


contentPane.add(label);
contentPane.add(combo);
      f.pack();
      f.show();
      f.addWindowListener(new WindowAdapter(){
    public void windowClosing(WindowEvent e){
    System.exit(0); 
    }
      });   
}
   public static void main(String[] args){
   new JComboBox8();
   }
   public void actionPerformed(ActionEvent e){
   boolean isaddItem=true;
   int fontsize=0;
   String tmp=(String)combo.getSelectedItem();
   //判斷用戶所輸入的項目是否有重複,若有重複則不增加到JComboBox中。
   try{
   fontsize=Integer.parseInt(tmp);
   for(int i=0;i<combo.getItemCount();i++){
   if (combo.getItemAt(i).equals(tmp)){
   isaddItem=false;
   break;
   }
   }
   if (isaddItem){
   combo.insertItemAt(tmp,0);//插入項目tmp到0索引位置(第一列中).
   }
   font=new Font("SansSerif",Font.PLAIN,fontsize);
   label.setFont(font);   
   }catch(NumberFormatException ne){
   combo.getEditor().setItem("你輸入的值不是整數值,請重新輸入!");
   }
   }
   public void itemStateChanged(ItemEvent e){//ItemListener界面只有itemStateChanged()一個方法,在此實作它。
   if (e.getStateChange()==ItemEvent.SELECTED){//當用戶的選擇改變時,則在JLabel上會顯示出Swing目前字形大小信息.
   int fontsize=0;
   try{
   fontsize=Integer.parseInt((String)e.getItem());
   label.setText("Swing 目前字形大小:"+fontsize);   
   }catch(NumberFormatException ne){//若所輸入的值不是整數,則不作任何的操作.
   
   }
   }
   }
}


-------------------------------------------------------------轉載自http://www.cnblogs.com/zhangxz/archive/2012/10/11/2720241.html
發佈了31 篇原創文章 · 獲贊 11 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章