`

JAVA组件大全 复选框、选项按钮、列表方框、下拉式列表的使用与介绍

阅读更多
7-1:使用JCheckBox组件:
类层次结构图:
  java.lang.Object
    --java.awt.Component
     --java.awt.Container
       --javax.swing.JComponent
          --javax.swing.AbstractButton
            --javax.swing.JToggleButton
              --javax.swing.JCheckBox
   JCheckBox与JRadioButton为JToggleButton的子类,因此它们可以使用AbstractButton抽象类里面许多好用的方法,如addItemLi
stener()、setText()、isSelected()等等。
构造函数:
   JCheckBox():建立一个新的JChcekBox.
   JCheckBox(Icon icon):建立一个有图像但没有文字的JCheckBox.
   JCheckBox(Icon icon,boolean selected):建立一个有图像但没有文字的JCheckBox,且设置其初始状态(有无被选取)。  
   JCheckBox(String text):建立一个有文字的JCheckBox.
   JCheckBox(String text,boolean selected):建立一个有文字的JCheckBox,且设置其初始状态(有无被选取)。
   JCheckBox(String text,Icon icon):建立一个有文字且有图像的JCheckBox,初始状态为无被选取。
   JCheckBox(String text,Icon icon,boolean selected):建立一个有文字且有图像的JCheckBox,且设置其初始状态(有无被选取
                                                      )。
7-1-1:构造JCheckBox组件:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class JCheckBox1{
  public static void main(String[] args){
     JFrame f=new JFrame("JCheckBox1");
     Container contentPane=f.getContentPane();
     contentPane.setLayout(new GridLayout(2,1));
     JPanel p1=new JPanel();
     p1.setLayout(new GridLayout(1,3));
     p1.setBorder(BorderFactory.createTitledBorder("你最喜欢哪一家快餐店呢?"));
     JCheckBox c1=new JCheckBox("麦当劳");
     JCheckBox c2=new JCheckBox("肯德基");
     JCheckBox c3=new JCheckBox("21世纪");
     p1.add(c1);
     p1.add(c2);
     p1.add(c3);
     JPanel p2=new JPanel();
     p2.setLayout(new GridLayout(2,1));
     p2.setBorder(BorderFactory.createTitledBorder("以下为JCheckBox的图形示范:"));
     JCheckBox c4=new JCheckBox("图形1",new ImageIcon(".\\icons\\x.jpg"));
     JCheckBox c5=new JCheckBox("图形2",new ImageIcon(".\\icons\\x.jpg"));
     p2.add(c4);
     p2.add(c5);
     contentPane.add(p1);
     contentPane.add(p2);
     f.pack();
     f.show();
       f.addWindowListener(new WindowAdapter(){
           public void windowClosing(WindowEvent e){
              System.exit(0);
           }
       });
  }
}

7-1-2:JCheckBox事件处理:
     你可以在上面的选项中勾选你喜欢吃的快餐店,在勾选的过程中,你可以发现它是可以复选的。但在图形选项中,我们并无法
清楚用户是否选择此项目,因为选或不选图形都一样。为解决这个问题,我们要使用到事件处理方法。当JCheckBox中的选项被选取
或取消时,它会触发ItemEvent的事件,ItemEvent这个类共提供了4种方法可以使用,分别是getItem()、getItemSelectable()、
getStateChange()、paramString()。getItem()与paramString()方法会返回一些这个JCheckBox的状态值。一般我们较少用到这两
个方法。
    getItemSelectable()相当于getSource()方法,一样都是返回触发事件的组件,用来判断是那个组件产生事件。在上一章中我
们曾经说过,getSource()方法是EventObject类所提供,而所有事件类都会继承这个类,因此所有的事件我们均能用getSource()
方法来判断到底是哪个组件触发了事件。
   最后getStateChange()方法会返回此组件到底有没有被选取。这个方法会返回一个整数值。而我们可以用ItemEvent所提供的类
变量;若被选取则返回SELECTED,若没有被选取则返回DESELECTED.
   下面这个范例我们即利用ItemListener来选取图形产生变化,ItemListener这个inteface只有定义一个方法,那就是
itemStateChange(ItemEvent e),因此我们只需实作这个方法.


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

public class JCheckBox2 implements ItemListener
{
    JFrame f = null;
    JCheckBox c4 = null;
    JCheckBox c5 = null;
   
    JCheckBox2(){
        f = new JFrame("JCheckBox");
        Container contentPane = f.getContentPane();
        contentPane.setLayout(new GridLayout(2,1));
        JPanel p1 = new JPanel();
        p1.setLayout(new GridLayout(1,3));
        p1.setBorder(BorderFactory.createTitledBorder("您最喜欢哪一家速食店呢?"));
        JCheckBox c1 = new JCheckBox("麦当劳");
        JCheckBox c2 = new JCheckBox("肯德鸡");
        JCheckBox c3 = new JCheckBox("21世纪");
        p1.add(c1);
        p1.add(c2);
        p1.add(c3);
        JPanel p2 = new JPanel();
        p2.setLayout(new GridLayout(2,1));
        p2.setBorder(BorderFactory.createTitledBorder("您喜欢哪种程序语言,喜欢的请打勾:"));
        c4 = new JCheckBox("JAVA",new ImageIcon(".\\icons\\x.jpg"));
        c5 = new JCheckBox("C++",new ImageIcon(".\\icons\\x.jpg"));
        c4.addItemListener(this);
        c5.addItemListener(this);
        p2.add(c4);
        p2.add(c5);
        contentPane.add(p1);
        contentPane.add(p2);
        f.pack();
        f.show();
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                    System.exit(0);
            }
        });
    }
   
    public void itemStateChanged(ItemEvent e)
    {
        if (e.getStateChange() == e.SELECTED)
        {
            if(e.getSource() == c4)
                c4.setIcon(new ImageIcon(".\\icons\\r.jpg"));
            if(e.getSource() == c5)
                c5.setIcon(new ImageIcon(".\\icons\\r.jpg"));
           
        }
        else
        {
            if(e.getSource() == c4)
                c4.setIcon(new ImageIcon(".\\icons\\x.jpg"));
            if(e.getSource() == c5)
                c5.setIcon(new ImageIcon(".\\icons\\x.jpg"));
        }
    }
     
    public static void main(String args[])
    {
        new JCheckBox2();
    }
}
7-2:JRadioButton的使用:
   java.lang.Object
    --java.awt.Component
      --java.awt.Container
       --javax.swing.JComponent
        --javax.swing.Abstractbutton
         --javax.swing.JToggleButton
            --javax.swing.JRadioButton

   JRadioButtonBN J JToggleButton的一个了类,因此它也可以使用AbstractButton抽象类里的方法。如同前面所述,JChexkBox
主要用在多重选择时机,而JRadioButton则是运用在单一选择时机。
  JRadioButton构造函数:
   JRadioButton():建立一个新的JRadioButton.
   JRadioButton(Icon icon):建立一个有图像但没有文字的JRadioButton.
   JRadioButton(Icon icon,boolean selected):建立一个有图像但没有文字的JRadioButton,且设置其初始状态(有无被选取).  
   JRadioButton(String text):建立一个有文字的JRadioButton.
   JRadioButton(String text,boolean selected):建立一个有文字的JRadioButton,且设置其初始状态(有无被选取)。
   JRadioButton(String text,Icon icon):建立一个有文字且有图像的JRadioButton,初始状态为无被选取。
   JRadioButton(String text,Icon icon,boolean selected):建立一个有文字且有图像的JRadioButton,且设置其初始状态(有无
                                                   被选取。
7-2-1:构造JRadioButton组件与事件处理:

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

public class JRadioButton1 implements ItemListener
{
    JFrame f = null;
    JRadioButton r4 = null;
    JRadioButton r5 = null;
   
    JRadioButton1(){
        f = new JFrame("JRadioButton");
        Container contentPane = f.getContentPane();
        contentPane.setLayout(new GridLayout(2,1));
        JPanel p1 = new JPanel();
        p1.setLayout(new GridLayout(1,3));
        p1.setBorder(BorderFactory.createTitledBorder("您最喜欢哪一家速食店呢?"));
        JRadioButton r1 = new JRadioButton("麦当劳");
        JRadioButton r2 = new JRadioButton("肯德鸡");
        JRadioButton r3 = new JRadioButton("21世纪");
        p1.add(r1);
        p1.add(r2);
        p1.add(r3);
        JPanel p2 = new JPanel();
        p2.setLayout(new GridLayout(2,1));
        p2.setBorder(BorderFactory.createTitledBorder("您喜欢哪种程序语言? 喜欢的请打勾"));
        r4 = new JRadioButton("JAVA",new ImageIcon(".\\icons\\x.jpg"));
        r5 = new JRadioButton("C++",new ImageIcon(".\\icons\\x.jpg"));
        r4.addItemListener(this);
        r5.addItemListener(this);
        p2.add(r4);
        p2.add(r5);
        contentPane.add(p1);
        contentPane.add(p2);
        f.pack();
        f.show();
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                    System.exit(0);
            }
        });
    }
   
    public void itemStateChanged(ItemEvent e)
    {
        if (e.getStateChange() == e.SELECTED)
        {
            if(e.getSource() == r4)
                r4.setIcon(new ImageIcon(".\\icons\\r.jpg"));
            if(e.getSource() == r5)
                r5.setIcon(new ImageIcon(".\\icons\\r.jpg"));
           
        }
        else
        {
            if(e.getSource() == r4)
                r4.setIcon(new ImageIcon(".\\icons\\x.jpg"));
            if(e.getSource() == r5)
                r5.setIcon(new ImageIcon(".\\icons\\x.jpg"));
        }
    }
     
    public static void main(String args[])
    {
        new JRadioButton1();
    }
}
   要将RadioButton改成单选,我们必须用到ButtonGroup这个类。这个类位于javax.swing这个package下面,ButtonGroup类的主
要功能是:同一时间内只会有一个组件的状态为"on",其他皆为"off",也就是同一时间只有一个组件会被选取。而ButtonGroup类可
被AbstractButton下面的子类所使用,最常被使用的就是JRadioButton、JradioButtonMenu、Item与JToggleButton这些组件。
下面是ButtonGroup的类层次结构图:
ButtonGroup的类层次结构图:
java.lang.Object
   --javax.swing.ButtonGroup
   我们更改上例,使RadioButton变成单选吧!

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

public class JRadioButton2 implements ItemListener{
  JFrame f=null;
  JRadioButton r4=null;
  JRadioButton r5=null;
 
  JRadioButton2(){
    f=new JFrame("JRadioButton2");
    Container contentPane=f.getContentPane();
    contentPane.setLayout(new GridLayout(2,1));
    JPanel p1=new JPanel();
    p1.setLayout(new GridLayout(1,3));
    p1.setBorder(BorderFactory.createTitledBorder("你最喜欢哪一家快餐店呢?"));
    JRadioButton r1=new JRadioButton("麦当劳");
    JRadioButton r2=new JRadioButton("肯德基");
    JRadioButton r3=new JRadioButton("21世纪");
    p1.add(r1);
    p1.add(r2);
    p1.add(r3);
/*
  将3个RadioButton对象放进ButtonGroup中,表示此3个RadioButton同一时间只有一个RadioButton的状态可以为"on";
*/
    ButtonGroup bgroup1=new ButtonGroup();
    bgroup1.add(r1);                         
    bgroup1.add(r2);                         
    bgroup1.add(r3);
    JPanel p2=new JPanel();
    p2.setLayout(new GridLayout(2,1));
    p2.setBorder(BorderFactory.createTitledBorder("你最喜欢哪种程序语言,喜欢的请打勾:"));                       
    r4=new JRadioButton("java",new ImageIcon(".\\icons\\x.jpg"));
    r5=new JRadioButton("c++",new ImageIcon(".\\icons\\x.jpg"));
    r4.addItemListener(this);
    r5.addItemListener(this);
    p2.add(r4);
    p2.add(r5);
    ButtonGroup bgroup2=new ButtonGroup();
    bgroup2.add(r4);
    bgroup2.add(r5);
    contentPane.add(p1);
    contentPane.add(p2);
    f.pack();
    f.show();
    f.addWindowListener(new WindowAdapter(){
        public void windowClosing(WindowEvent e){
        System.exit(0);
        }      
    });   
  }
  public void itemStateChanged(ItemEvent e){
    if (e.getStateChange()==e.SELECTED){
      if (e.getSource()==r4)
         r4.setIcon(new ImageIcon(".\\icons\\r.jpg"));
      if (e.getSource()==r5)
         r5.setIcon(new ImageIcon(".\\icons\\r.jpg"));
    }else{
      if (e.getSource()==r4)
         r4.setIcon(new ImageIcon(".\\icons\\x.jpg"));
      if (e.getSource()==r5)
         r5.setIcon(new ImageIcon(".\\icons\\x.jpg"));
    }
  }
  public static void main(String[] args){
    new JRadioButton2();
  }
}

7-3:JList的使用:
类层次结构图:
   java.lang.Object
     --java.awt.Component
      --java.awt.Container
       --javax.swing.JComponent
        --javax.swing.JList
    JList与JCheckBox有点相似,都可以让你选择一到多个选项,较不同的是,JList的选项方式是整列选取。我们先来看看JList
所提供的构造函数,方便迅速建立JList对象,如下所示:
JList构造函数:
JList():建立一个新的JList组件。
JList(ListModel dataModel):利用ListModel建立一个新的JList组件.
JList(Object[] listData):利用Array对象建立一个新的JList组件。
JList(Vector listData):利用Vector对象建立一个新的JList组件。

7-3-1:建立一般的JList:

一般我们若不需要在JList中加入Icon图像,通常会用第3或第4个构造函数建立JList对象。而这两个最大的不同在于使用Array对
象建立JList组件就无法改变项目的数量。对于项目数量经常改变的环境来说,以Vector对象来建立JList组件当然比较适合。例如
一个卖手机的店家,可能动不动就会有新手机上市,此时若用Array对象就不是很适当了!
我们来看个范例看怎么构造一个简单的JList吧!
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Vector;

public class JList1
{
    public static void main(String args[])
    {
        JFrame f = new JFrame("JList");
        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 V3688x");
        v.addElement("Panasonic GD92");
        v.addElement("其他");
       
        JList list1 = new JList(s);
        list1.setBorder(BorderFactory.createTitledBorder("您最喜欢到哪个国家玩呢?"));
       
        JList list2 = new JList(v);
        list2.setBorder(BorderFactory.createTitledBorder("您最喜欢哪一种手机?"));

        contentPane.add(new JScrollPane(list1));
        contentPane.add(new JScrollPane(list2));
        f.pack();
        f.show();
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                    System.exit(0);
            }
        });
    }
}
  在这个范例中,当窗口变小时,JList并不会有滚动(ScrollBar)的效果,所以可能无法看到比较下面的选项。若我们要有滚动的
效果,必须将JList放入滚动面版中(JScrollPane),如我们在程序改为:
       contentPane.add(new JScrollPane(list1));
       contentPane.add(new JScrollPane(list2));
  如此就有滚动的效果了,若我们要有多个选项呢?在JList中有3种选择模式(Selection Mode)可供我们使用,分别是单一选择、
连续区间选择、与多重选择。我们可以在ListSelectionModel这个interface中找到这3个常数值,如下:
    static int SINGLE_SELECTION:一次只能选择一个项目。
    static int SINGLE_INTERVAL_SELECTION:按住[shift]键,可以对某一边续的项目作选取。
    static int MULTIPLE_INTERVAL_SELECTION:没有任何限制。可作单一选择,连续区间选择,或对不连续的项目作多重选择(按
住[Ctrl]键)。多得选择是java对JList的默认值,因此在上例中你可以在JList中作这3种模式的选择方式。

    设置选择模式可以利用JList所提供的setSelectionMode(int selectionMode)方法。例如,若我们将上例改成如下:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Vector;

public class JList2
{
    public static void main(String args[])
    {
        JFrame f = new JFrame("JList");
        Container contentPane = f.getContentPane();
        contentPane.setLayout(new GridLayout(1,3));
        String[] s1 = {"美国","日本","大陆","英国","法国","意大利","澳洲","韩国"};
        String[] s2 = {"范志毅","符兵","周宁","杨晨","高锋","南方","其他"};
        Vector v = new Vector();
        v.addElement("Nokia 3310");
        v.addElement("Nokia 8850");
        v.addElement("Nokia 8250");
        v.addElement("Motorola V8088");
        v.addElement("Motorola V3688x");
        v.addElement("Panasonic GD92");
        v.addElement("Panasonic GD93");
        v.addElement("NEC DB2100");
        v.addElement("Alcatel OT500");
        v.addElement("Philips Xenium 9@9 ");
        v.addElement("Ericsson T29sc");
        v.addElement("其他");
       
        JList list1 = new JList(s1);
        list1.setBorder(BorderFactory.createTitledBorder("您最喜欢到哪个国家玩呢?"));
       
        JList list2 = new JList(s2);
        list2.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        list2.setBorder(BorderFactory.createTitledBorder("您最喜欢哪个运动员呢?"));
       
        JList list3 = new JList(v);
        list3.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
        list3.setBorder(BorderFactory.createTitledBorder("您最喜欢哪一种手机?"));

        contentPane.add(new JScrollPane(list1));
        contentPane.add(new JScrollPane(list2));
        contentPane.add(new JScrollPane(list3));
        f.pack();
        f.show();
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                    System.exit(0);
            }
        });
    }
}

7-3-2:利用ListModel构造JList:
  ListModel是一个interface,主要的功能是定义一些方法,让JList或JComboBox这些组件取得每个项目的值,并可限定项目的显示
时机与方式,下面为ListModel这个interface所定义的方法:
   ListModel interface定义的方法:
    void                    addListDataListener(ListDataListener l):当data model的长度或内容值有任何改变时,利用此
                            方法就可以处理ListDataListener的事件。data model是vector或array的数据类型,里面存放List
                            中的值。
    Object                  getElementAt(int index):返回在index位置的Item值。
    int                     getSize():返回List的长度。
    void                    removeListDataListener(ListDataListener l):删除ListDataListener.
  还记得我们一开始在介绍JList时所提到的构造函数吗?其中有一个JList的构造函数是这样的:
      JList(ListModel dataModel)
  因此我们必须实作ListModel所有的方法,才能利用上面这个构造函数建立JList.不过要实现ListModel所有的方法有点麻烦,因
为一般我们不会用到addListDataListener()与removeListDataListener()这两个方法。因此java提供了AbstractListModel这个抽
象类,此抽象类实作了addListDataListener()与removeListDataListener()这两个方法。若我们继承AbstractListModel,就不需
实现这两个方法,只需要实作getElementAt()与getSize()方法即可,我们来看下面的范例:

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

public class JList3{
  public JList3(){
     JFrame f=new JFrame("JList");
     Container contentPane=f.getContentPane();
     /*由于我们在DataModelodel类中继承AbstractListModel,并实作了getElementAt()与getSize()方法,因此
      *我们可以由DataModel类产生一个ListModel的实体来。
      */
     ListModel mode=new DataModel();
     JList list=new JList(mode);//利用ListModel建立一个JList.
     list.setVisibleRowCount(5);//设置程序一打开时所能看到的数据项个数。
     list.setBorder(BorderFactory.createTitledBorder("你最喜欢到哪个国家玩呢?"));
    
     contentPane.add(new JScrollPane(list));
     f.pack();
   /*当程序要show出list时,系统会先自动调用getSize()方法,看看这个list长度有多少;然后再调 用setVisibleRowCount()方
    法,看要一次输出几笔数据;最后调用getElementAt()方法,将list中的项目值(item)填入list中。读者若还不太清楚,可直接
    在getSize()与getElementAt()方法中个别加入System.out.println("size");与System.out.println("element")叙述,就可以
    在dos console清楚看出整个显示list调用的过程。
    */
     f.show();
     f.addWindowListener(new WindowAdapter(){
     public void windowClosing(WindowEvent e){
        System.exit(0);
     }
     });
  }
  public static void main(String[] args){
  new JList3();
  }
}
/*由于我们在下面程序中继承AbstractListModel抽象类,因此我们分别在下面程序中实现了getElementAt()与getSize()方法。
*/
class DataModel extends AbstractListModel{
  String[] s={"美国","越南","大陆","英国","法国","大陆","意大利","澳洲"};
  public Object getElementAt(int index){//getxElementAt()方法中的参数index,系统会自动由0开始计算,不过要自己作累加
                                        //的操作.
     return (index+1)+"."+s[index++];
  }
  public int getSize(){
  return s.length;
  }
}

  事实上,java本身还提供另一个类,DefaultListModel实体类。此类继承了AbstractListModel抽象类,并实现里面所有的抽象方
法,因此你不需要再自行实作任何的方法,可以说是相当的方便。不过既然所有的抽象都已经被实现,因此在设计的弹性上就会有
有所降低。若你是喜欢自行管理JList项目的设计者,你可以不要使用DefaultListModel这个类,只需要在AbstractListModel上多
下功夫即可。
  下面的例子我们改写上面的例子,直接使用DefaultListModel类:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Vector;

public class JList4
{
    public JList4()
    {
        JFrame f = new JFrame("JList");
        Container contentPane = f.getContentPane();
       
        ListModel mode = new DataModel();
        JList list = new JList(mode);
        list.setVisibleRowCount(5);
        list.setBorder(BorderFactory.createTitledBorder("您最喜欢到哪个国家玩呢?"));
       
        contentPane.add(new JScrollPane(list));
        f.pack();
        f.show();
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                    System.exit(0);
            }
        });
    }
   
    public static void main(String args[])
    {
        new JList4();
    }
}
/*使DataModel继承DefaultListModel实体类,因此就不需要再实作getSize()与getElementAt()两个方法,
*直接将所要的项目用addElementAt()方法加入即可。系统会自动将所加入的项目放入一个Vector对象中,
*并在输出JList时自动调用getSize()与getElementAt()方法。你可以在DefaultListModel类中找到getSize()与
*getElementAt()两个方法,你可以发现这两个方法已经被实作,不再是抽象方法了。
*/
class DataModel extends DefaultListModel
{
    String[] s = {"美国"," 日本","大陆","英国","法国","意大利","澳洲","韩国"};
   
    DataModel()
    {
        for(int i=0; i < s.length; i++)
            addElement((i+1)+"."+s[i]);
    }
}

  程序运行结果与上个范例相同。
  好奇怪,这不是跟我们使用Vector方式,利用JList(Vector v)构造函数来建立新的JList一样吗?如同JList1.java中的例子,为
什么还要多此一举呢?其实若读者去查看DefaultListModel类,可发现此类提供不少好用的方法,例如你可以随意的增加一个项目(
addElement())、或是删除一个项目(removeElement)、甚至你可以很方便地做到查询(getElementAt())与汇出(copyInto())项目的
操作。你可以发现,利用DefaultListModel可以直接动态地更改JList的项目值,而不需要自行产生一个Vecotr对象;相对于JList(
Vector v)这个构造函数,可说更方便且实用许多.
  至于利用ListModel或AbstractListModel来构造JList有什么好处?读者只要这么想,ListModel中文就是“列出模式”,那么每
个老师都会有自己开课的学生成绩,老师应该可以看到每个同学的成绩,而深长应该只能看到自己的成绩,所以我们就会有两种不
同的“列出模式”。我们只需要去改写getElementAt()方法,就会有不同的列出模式产生,如下面的范例:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Vector;

public class JList5
{
    public JList5()
    {
        JFrame f = new JFrame("JList");
        Container contentPane = f.getContentPane();
        contentPane.setLayout(new GridLayout(1,2));
        ListModel mode = new DataModel(1);
        JList list1 = new JList(mode);
        list1.setVisibleRowCount(5);
        list1.setBorder(BorderFactory.createTitledBorder("您玩过哪些软件?"));
       
        mode = new DataModel(2);
        JList list2 = new JList(mode);
        list2.setBorder(BorderFactory.createTitledBorder("您玩过哪些数据库软件?"));
       
        contentPane.add(new JScrollPane(list1));
        contentPane.add(new JScrollPane(list2));
        f.pack();
        f.show();
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                    System.exit(0);
            }
        });
    }
   
    public static void main(String args[])
    {
        new JList5();
    }
}

class DataModel extends AbstractListModel
{
    String[] s = {"MS SQL","MySQL","IBM DB2","ORACLE","Windows 2000","Linux","UNix","OS2"};
    int flag;
   
    DataModel(int flag)
    {
        this.flag = flag;
    }
    public Object getElementAt(int index)
    {
        String tmp = null;
       
        if (flag == 1)
            tmp = (index+1)+"."+s[index++];
        if (flag == 2)
        {
            if(index < 4)
                tmp = (index+1)+"."+s[index++];    
        }
       
        return tmp;
    }
   
    public int getSize()
    {
        return s.length;
    }
}



7-3-3:建立有图像的JList:
  我们也可以在JList中加入Icon图像,不过JList加入图像比较麻烦一点,不像JLabel或JButton那样简单。要在JList上加入Icon,
要先了解ListCellRenderer interface.我们必须由这个interface所定义的方法,将图像画在JList中的每个项目。
ListCellRenderer interface里只定义了一个方法,那就是getListCellRendererComponent,不过这个参数有点多,我们把它列出来
看看:
public Component getListCellRendererComponent(JList list,
                                              Object value,
                                              int index,
                                              boolean isSelected,
                                              boolean cellHasFocus)
list:即所要画上的图像的JList组件。
value:JList项目值,如list.getModel().getElementAt(index)所返回的值。
index:为JList项目的索引值,由0开始。
isSelected与cellHasFocus:判断JList中的项目是否有被选取或是有焦点置入。
  上面这4个参数会在你设置JList的绘图样式(setCellRenderer())时自动的由JList组件提供,你只要关心怎么控制
getListCellRendererComponent()方法中的4个参数,而无需担心怎么参数传入。
   要在JList中加入Icon图像的技巧就是将JList中的每一个项目当作是JLabel,因为JLabel在使用文字与图像上非常的方便,要设置
JList的图像,必须使用setCellRenderer(ListCellRenderer cellRenderer)这个方法。我们来看下面这个范例,你就能明白了!
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Vector;

public class JList6
{
    public JList6()
    {
        String[] s = {"西瓜","苹果","草莓","香蕉","葡萄"};
        JFrame f = new JFrame("JList");
        Container contentPane = f.getContentPane();
        JList list1 = new JList(s);
        list1.setBorder(BorderFactory.createTitledBorder("您喜欢吃哪些水果?"));
        /*设置在JList中画上图像。在此参数中,我们产生一个CellRenderer对象,此对象实作了ListCellRenderer interface,
         *因此可以返回一个ListCellRenderer对象当作setCellRenderer()方法的参数.
         */
        list1.setCellRenderer(new CellRenderer());
       
        contentPane.add(new JScrollPane(list1));
        f.pack();
        f.show();
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                    System.exit(0);
            }
        });
    }
   
    public static void main(String args[])
    {
        new JList6();
    }
}

class CellRenderer extends JLabel implements ListCellRenderer
{
   /*类CellRenderer继承JLabel并实作ListCellRenderer.由于我们利用JLabel易于插图的特性,因此CellRenderer继承了JLabel
    *可让JList中的每个项目都视为是一个JLabel.
    */
    CellRenderer()
    {
        setOpaque(true);
    }
    /*从这里到结束:实作getListCellRendererComponent()方法*/
    public Component getListCellRendererComponent(JList list,
                                                  Object value,
                                                  int index,
                                                  boolean isSelected,
                                                  boolean cellHasFocus)
    {  
        /*我们判断list.getModel().getElementAt(index)所返回的值是否为null,例如上个例子中,若JList的标题是"你玩过哪
         *些数据库软件",则index>=4的项目值我们全都设为null.而在这个例子中,因为不会有null值,因此有没有加上这个判
         *断并没有关系.
         */
        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;
    }   
}

7-3-4:JList的事件处理:
   JList的事件处理一般可分为两种:一种是取得用户选取的项目;另一种是在JList的项目上双击鼠标两次,运行相对应的工作。我
们先来看第一种事件处理方式:
    在JList类中有addListSelectionListener()方法,可以检测用户是否对JList的选取有任何的改变。ListSelectionListener
interface中只有定义一个方法,那就是valueChanged(ListSelectionEvent e),我们必须实作这个方法,才能在用户改变选取值时
取得用户最后的选取状态。我们来看一下的例子: 这个例子匀们抓取用户所选取的项目,并将所选的项目显示在JLabel上。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;//由于ListSelectionEvent是swing的事件,不是awt的事件,因此我们必须import
                            //javax.swing.event.*。

public class JList7 implements ListSelectionListener
{
    JList list = null;
    JLabel label = null;
    String[] s = {"美国","日本","大陆","英国","法国","意大利","澳洲","韩国"};
   
    public JList7()
    {
        JFrame f = new JFrame("JList");
        Container contentPane = f.getContentPane();
        contentPane.setLayout(new BorderLayout());
        label = new JLabel();
       
        list = new JList(s);
        list.setVisibleRowCount(5);
        list.setBorder(BorderFactory.createTitledBorder("您最喜欢到哪个国家玩呢?"));
        list.addListSelectionListener(this);
       
        contentPane.add(label,BorderLayout.NORTH);
        contentPane.add(new JScrollPane(list),BorderLayout.CENTER);
        f.pack();
        f.show();
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                    System.exit(0);
            }
        });
    }
   
    public static void main(String args[])
    {
        new JList7();
    }
   
    public void valueChanged(ListSelectionEvent e)
    {
        int tmp = 0;
        String stmp = "您目前选取:";
        int[] index = list.getSelectedIndices();//利用JList类所提供的getSelectedIndices()方法可得到用户所选取的所有
        for(int i=0; i < index.length ; i++)//index值,这些index值由一个int array返回.
        {
            tmp = index[i];
            stmp = stmp+s[tmp]+"  ";
        }
        label.setText(stmp);
    }
}

   接下来,我们来看如何处理在JList上双击鼠标的操作。由于JList本身并无提供这样的EventListener,因此我们必须利用
MouseListener来达到捕获双击鼠标的事件。至于要怎么知道我们到底在哪个项目上双击鼠标呢?我们可以利用JList类所提供的
LocatToindex()方法得知。以下为我们所举的范例:
   这个例子一开始左边列有国这名称,当你在某个国家名称上双击鼠标,这个国家名称就会移到右边去,反之亦同。
   1.这个范例我们应用DefaultListModel类,因主DefaultListModel类实作了Vector中的方法,使我们在处理动态的JList项目值 
     比较容易.
   2.由于我们要处理鼠标事件,为了编写方便,在程序中我们继承MouseAdapte抽象类.
   3.在程序中,我们建立两个DataModel,第一个JList,也就是list1一开始时会将String Array s中的所有值依次放入list1的项
     目中,而list2一开始为空白。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class JList8 extends MouseAdapter{
  JList list1=null;
  JList list2=null;
  DefaultListModel mode1=null;
  DefaultListModel mode2=null;
  String[] s = {"美国","日本","大陆","英国","法国","意大利","澳洲","韩国"};
 
  public JList8(){
  JFrame f=new JFrame("JList");
  Container contentPane=f.getContentPane();
  contentPane.setLayout(new GridLayout(1,2));
 
  mode1=new DataModel(1);
  list1=new JList(mode1);
  list1.setBorder(BorderFactory.createTitledBorder("国家名称!"));
  list1.addMouseListener(this);//一遇到鼠标事件立即执行.
 
  mode2=new DataModel(2);
  list2=new JList(mode2);
  list2.setBorder(BorderFactory.createTitledBorder("你最喜欢到哪个国家玩呢!"));
  list2.addMouseListener(this);//一遇到鼠标事件立即执行.
 
  contentPane.add(new JScrollPane(list1));
  contentPane.add(new JScrollPane(list2));
   f.pack();
   f.show();
   f.addWindowListener(new WindowAdapter(){
      public void windowClosing(WindowEvent e){
         System.exit(0);
      }
   });   
  }
  public static void main(String[] args){
  new JList8();
  }
//处理鼠标键击事件.
  public void mouseClicked(MouseEvent e){
  int index;
    /*对list1而言,当鼠标在某个项目连续按两下时,我们利用JList所提供的locationToIndex()方法,找到所键击的项目,并
     *由tmp取得此项目的项目值,然后将此项目值增加到mode2中[mode2.addElement(tmp)],用setModel重新设置list2的
     *ListModel,使list2可显示出所增加的项目,将刚刚在list1双击的项目删除.
     */
  if (e.getSource()==list1){
     if (e.getClickCount()==2){
        index=list1.locationToIndex(e.getPoint());
        String tmp=(String)mode1.getElementAt(index);
        mode2 .addElement(tmp);
        list2.setModel(mode2);
        mode1.removeElementAt(index);
        list1.setModel(mode1);
     }
  }
  if (e.getSource()==list2){
     if (e.getClickCount()==2){
        index=list2.locationToIndex(e.getPoint());
        String tmp=(String)mode2.getElementAt(index);
        mode1 .addElement(tmp);
        list1.setModel(mode1);
        mode2.removeElementAt(index);
        list2.setModel(mode2);
     }
  }
  }
  class DataModel extends DefaultListModel{
    DataModel(int flag){
      if (flag==1){
      for (int i=0;i<s.length;i++)  addElement(s[i]);      
      }
    }
  }
}
 
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){//若所输入的值不是整数,则不作任何的操作.
      
       }
     }
   }



本文来自CSDN博客
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics