Swing JComboBox的使用
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 }