1:JComboBox的使用:
類層次結構圖:
1 java.lang.Object 2 --java.awt.Component 3 --java.awt.Container 4 --javax.swing.JComponent 5 --javax.swing.JComboBox
構造函數:
1 JComboBox():建立一個新的JComboBox組件。 2 JComboBox(ComboBoxModel aModel):用ListModel建立一個新的JComboBox組件。 3 JComboBox(Object[] items):利用Array對象建立一個新的JComboBox組件。 4 JComboBox(Vector items):利用Vector對象建立一個新的JComboBox組件。
1-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); } }); } }
1-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()方法。
1-3:建立有圖像的JComboBox:
在上一節中我們利用ListCellRenderer interface在JList中加入Icon圖像,而要在JComboBox中加入圖像的方法也是一樣的。
我們必須實作ListCellRenderer interface所定義的方法getListCellRendererComponent.以下為這個方法的定義:
要先了解ListCellRenderer interface.我們必須由這個interface所定義的方法,將圖像畫在JComboBox中的每個項目。
ListCellRenderer interface里只定義了一個方法,那就是getListCellRendererComponent,不過這個參數有點多,我們把它列出來
看看:
1 public Component getListCellRendererComponent(JList list, 2 Object value, 3 int index, 4 boolean isSelected, 5 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)方法,讀者請小心}這個方法。我們來看下面這個范例,你就能明白了!
1 import java.awt.*; 2 import java.awt.event.*; 3 import javax.swing.*; 4 5 public class JComboBox4{ 6 String[] s={"西瓜","蘋果","草莓","香蕉","葡萄"}; 7 public JComboBox4(){ 8 JFrame f=new JFrame("JComboBox"); 9 Container contentPane=f.getContentPane(); 10 11 JComboBox combo=new JComboBox(s); 12 combo.setBorder(BorderFactory.createTitledBorder("你最喜歡吃哪些水果?")); 13 combo.setRenderer(new ACellRenderer()); 14 combo.setMaximumRowCount(3); 15 16 contentPane.add(combo); 17 f.pack(); 18 f.show(); 19 f.addWindowListener(new WindowAdapter(){ 20 public void windowClosing(WindowEvent e){ 21 System.exit(0); 22 } 23 }); 24 } 25 public static void main(String[] args){ 26 new JComboBox4(); 27 } 28 } 29 class ACellRenderer extends JLabel implements ListCellRenderer{ 30 ACellRenderer(){ 31 setOpaque(true); 32 } 33 public Component getListCellRendererComponent(JList list, 34 Object value, 35 int index, 36 boolean isSelected, 37 boolean cellHasFocus){ 38 if (value!=null){ 39 setText(value.toString()); 40 setIcon(new ImageIcon(".\\icons\\fruit"+(index+1)+".jpg")); 41 } 42 if (isSelected){ 43 setBackground(list.getSelectionBackground()); 44 setForeground(list.getSelectionForeground()); 45 }else{ 46 setBackground(list.getBackground()); 47 setForeground(list.getForeground()); 48 } 49 return this; 50 } 51 }
各們讀者在運行這個程序時會發現,即使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不應該只有文字,而必須連圖標一
並傳入。我們修改上個范例修改如下:
1 import java.awt.*; 2 import java.awt.event.*; 3 import javax.swing.*; 4 5 public class JComboBox5 6 { 7 String[] s = {"西瓜","蘋果","草莓","香蕉","葡萄"}; 8 ImageIcon[] icons = new ImageIcon[5];; 9 10 public JComboBox5() 11 { 12 JFrame f = new JFrame("JComboBox"); 13 Container contentPane = f.getContentPane(); 14 ItemObj[] obj = new ItemObj[5]; 15 16 for(int i=0; i < 5; i++) 17 { 18 icons[i] = new ImageIcon(".\\icons\\fruit"+(i+1)+".jpg"); 19 obj[i] = new ItemObj(s[i],icons[i]); 20 } 21 22 JComboBox combo = new JComboBox(obj);//利用ItemObj Array obj當作是JComboBox的參數傳入,構造出JComboBox. 23 combo.setBorder(BorderFactory.createTitledBorder("您喜歡吃哪些水果?")); 24 combo.setRenderer(new ACellRenderer()); 25 combo.setMaximumRowCount(3); 26 27 contentPane.add(combo); 28 f.pack(); 29 f.show(); 30 f.addWindowListener(new WindowAdapter() { 31 public void windowClosing(WindowEvent e) { 32 System.exit(0); 33 } 34 }); 35 } 36 37 public static void main(String args[]) 38 { 39 new JComboBox5(); 40 } 41 } 42 43 class ItemObj 44 { 45 String name; 46 ImageIcon icon; 47 48 public ItemObj(String name, ImageIcon icon){ 49 this.name = name; 50 this.icon = icon; 51 } 52 } 53 54 class ACellRenderer extends JLabel implements ListCellRenderer 55 { 56 ACellRenderer() 57 { 58 setOpaque(true); 59 } 60 61 public Component getListCellRendererComponent(JList list, 62 Object value, 63 int index, 64 boolean isSelected, 65 boolean cellHasFocus) 66 { 67 if (value != null) 68 { 69 setText(((ItemObj)value).name); 70 setIcon(((ItemObj)value).icon); 71 } 72 73 if (isSelected) { 74 setBackground(list.getSelectionBackground()); 75 setForeground(list.getSelectionForeground()); 76 } 77 else { 78 setBackground(list.getBackground()); 79 setForeground(list.getForeground()); 80 } 81 82 return this; 83 } 84 }
你可以發現,第一欄顯示有圖標顯示出來了。當然你也可以利用ComboBoxModel方式來構造出有圖標的JComboBox.我們來看下面
的例子:
1 import java.awt.*; 2 import java.awt.event.*; 3 import javax.swing.*; 4 5 public class JComboBox6{ 6 String[] s={"西瓜","蘋果","草莓","香蕉","葡萄"}; 7 ImageIcon[] icons=new ImageIcon[5]; 8 public JComboBox6(){ 9 JFrame f=new JFrame("JComboBox"); 10 Container contentPane=f.getContentPane(); 11 for(int i=0; i < 5; i++) 12 { 13 icons[i] = new ImageIcon(".\\icons\\fruit"+(i+1)+".jpg"); 14 } 15 ComboBoxModel mode=new AModel(); 16 JComboBox combo=new JComboBox(mode); 17 combo.setBorder(BorderFactory.createTitledBorder("您喜歡吃哪些水果?")); 18 combo.setRenderer(new ACellRenderer()); 19 combo.setMaximumRowCount(3); 20 21 contentPane.add(combo); 22 f.pack(); 23 f.show(); 24 f.addWindowListener(new WindowAdapter() { 25 public void windowClosing(WindowEvent e) { 26 System.exit(0); 27 } 28 }); 29 } 30 public static void main(String[] args){ 31 new JComboBox6(); 32 } 33 /*我們用JComboBox(ComboBoxModel aModel)來構造圖標的JComboBox,因此我們在程序中編寫一個繼承DefaultComboBoxModel的 34 ComboBoxModel. 35 */ 36 class AModel extends DefaultComboBoxModel{ 37 AModel(){ 38 for (int i=0;i<s.length;i++){ 39 ItemObj obj=new ItemObj(s[i],icons[i]); 40 addElement(obj); 41 } 42 } 43 } 44 } 45 class ItemObj 46 { 47 String name; 48 ImageIcon icon; 49 50 public ItemObj(String name, ImageIcon icon){ 51 this.name = name; 52 this.icon = icon; 53 } 54 } 55 56 class ACellRenderer extends JLabel implements ListCellRenderer 57 { 58 ACellRenderer() 59 { 60 setOpaque(true); 61 } 62 63 public Component getListCellRendererComponent(JList list, 64 Object value, 65 int index, 66 boolean isSelected, 67 boolean cellHasFocus) 68 { 69 if (value != null) 70 { 71 setText(((ItemObj)value).name); 72 setIcon(((ItemObj)value).icon); 73 } 74 75 if (isSelected) { 76 setBackground(list.getSelectionBackground()); 77 setForeground(list.getSelectionForeground()); 78 } 79 else { 80 setBackground(list.getBackground()); 81 setForeground(list.getForeground()); 82 } 83 84 return this; 85 } 86 } 87 88 我們用JComboBox(ComboBoxModel aModel)來構造圖標的JComboBox,因此我們在程序中編寫一個繼承DefaultComboBoxModel的 89 ComboBoxModel.
1-4:建立可自行輸入的JComboBox:
1 import java.awt.*; 2 import java.awt.event.*; 3 import javax.swing.*; 4 5 public class JComboBox7 6 { 7 String[] fontsize = {"12","14","16","18","20","22","24","26","28"}; 8 String defaultMessage = "請選擇或直接輸入文字大小!"; 9 10 public JComboBox7() 11 { 12 JFrame f = new JFrame("JComboBox"); 13 Container contentPane = f.getContentPane(); 14 15 JComboBox combo = new JComboBox(fontsize); 16 combo.setBorder(BorderFactory.createTitledBorder("請選擇你要的文字大小")); 17 combo.setEditable(true);//將JComboBox設成是可編輯的. 18 ComboBoxEditor editor = combo.getEditor();//getEditor()方法返回ComboBoxEditor對象,如果你查看手冊,你就會發 19 //現ComboBoxEditor是個接口(interface),因此你可以自行實作這個接口,制作自己想要的ComboBoxEditor組件。但通常 20 //我們不需要這么做,因為默認的ComboBoxEditor是使用JTextField,這已經足夠應付大部份的情況了。 21 22 //configureEditor()方法會初始化JComboBox的顯示項目。例如例子中一開始就出現:"請選擇或直接輸入文字大小!"這個 23 //字符串。 24 combo.configureEditor(editor, defaultMessage); 25 26 contentPane.add(combo); 27 f.pack(); 28 f.show(); 29 f.addWindowListener(new WindowAdapter() { 30 public void windowClosing(WindowEvent e) { 31 System.exit(0); 32 } 33 }); 34 } 35 36 public static void main(String args[]) 37 { 38 new JComboBox7(); 39 } 40 }
1-5:JComboBox的事件處理:
JComboBox的事件處理亦可分為兩種,一種是取得用戶選取的項目;另一種是用戶在JComboBox上自行輸入完畢后按下[Enter]鍵,
運作相對應的工作。對於第一種事件的處理,我們使用ItemListener.對於第二種事件的處理,我們使用ActionListener.
這個范例用戶可以選取所要的字號,字號的變化會呈現在JLabel上,並可讓用戶自行輸入字體的大小。當用戶按下[Enter]鍵后
,若用戶輸入的值不在選項上時,此輸入值會增加至JComboBox中,並將輸入字體的大小顯示在JLabel上。
1 import java.awt.*; 2 import java.awt.event.*; 3 import javax.swing.*; 4 5 public class JComboBox8 implements ItemListener,ActionListener{ 6 String[] fontsize={"12","14","16","18","20","22","24","26","28"}; 7 String defaultMessage="請選擇或直接輸入文字大小!"; 8 Font font=null; 9 JComboBox combo=null; 10 JLabel label=null; 11 12 public JComboBox8(){ 13 JFrame f=new JFrame("JComboBox"); 14 Container contentPane=f.getContentPane(); 15 contentPane.setLayout(new GridLayout(2,1)); 16 label=new JLabel("Swing",JLabel.CENTER); 17 font=new Font("SansSerif",Font.PLAIN,12); 18 label.setFont(font); 19 20 combo=new JComboBox(fontsize); 21 combo.setBorder(BorderFactory.createTitledBorder("請選擇你要的文字大小:")); 22 combo.setEditable(true); 23 ComboBoxEditor editor=combo.getEditor(); 24 combo.configureEditor(editor,defaultMessage); 25 combo.addItemListener(this);0 26 combo.addActionListener(this); 27 28 contentPane.add(label); 29 contentPane.add(combo); 30 f.pack(); 31 f.show(); 32 f.addWindowListener(new WindowAdapter(){ 33 public void windowClosing(WindowEvent e){ 34 System.exit(0); 35 } 36 }); 37 } 38 public static void main(String[] args){ 39 new JComboBox8(); 40 } 41 public void actionPerformed(ActionEvent e){ 42 boolean isaddItem=true; 43 int fontsize=0; 44 String tmp=(String)combo.getSelectedItem(); 45 //判斷用戶所輸入的項目是否有重復,若有重復則不增加到JComboBox中。 46 try{ 47 fontsize=Integer.parseInt(tmp); 48 for(int i=0;i<combo.getItemCount();i++){ 49 if (combo.getItemAt(i).equals(tmp)){ 50 isaddItem=false; 51 break; 52 } 53 } 54 if (isaddItem){ 55 combo.insertItemAt(tmp,0);//插入項目tmp到0索引位置(第一列中). 56 } 57 font=new Font("SansSerif",Font.PLAIN,fontsize); 58 label.setFont(font); 59 }catch(NumberFormatException ne){ 60 combo.getEditor().setItem("你輸入的值不是整數值,請重新輸入!"); 61 } 62 } 63 public void itemStateChanged(ItemEvent e){//ItemListener界面只有itemStateChanged()一個方法,在此實作它。 64 if (e.getStateChange()==ItemEvent.SELECTED){//當用戶的選擇改變時,則在JLabel上會顯示出Swing目前字形大小信息. 65 int fontsize=0; 66 try{ 67 fontsize=Integer.parseInt((String)e.getItem()); 68 label.setText("Swing 目前字形大小:"+fontsize); 69 }catch(NumberFormatException ne){//若所輸入的值不是整數,則不作任何的操作. 70 71 } 72 } 73 } 74 }