zeyuphoenix

愿我爱的人快乐,愿爱我的人快乐,为了这些,我愿意不快乐.

JList列表框

JListJCombobox组件从本质上说是类似的,它们都是提供了一系列列表数据供用户选择,从表现形式上可以把JCombobox看做一个JList和一个JTextField组成,通过callback机制回调选择项目.JList并没有复杂的UI,当然也就没有复杂的画面了,所以对于提高JList的画面表现,一般继承ListCellRenderer加入自己的表现样式就可以了,当然依照SwingMVC原则,需要修改数据时,实现ListModel接口就可以了,对选择样式修改,实现ListSelectionModel接口就可以了,它们的实现都相对简单,功能也相对简单,一般都不需要实现,对于复杂画面样式也不推荐JList,单列的JTable和自己实现的JTree比它好很多.

JList的基本使用很简单,先看Sun官方的使用例子:

界面如下:

只需要新创建一个DefaultListModel,赋予需要显示的值就可以了.

    DefaultListModel listModel = new DefaultListModel();

    listModel.addElement("Debbie Scott");

    listModel.addElement("Scott Hommel");

    listModel.addElement("Sharon Zakhour");

然后创建JList

JList list = new JList(listModel);

list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

当然可以给它加监听:

list.addListSelectionListener(this);

也可以加鼠标的Click监听,这是所有JComponent都具有的能力.

然后实现监听就可以了:

    // This method is required by ListSelectionListener.

    publicvoid valueChanged(ListSelectionEvent e) {

       if (e.getValueIsAdjusting() == false) {

最后把创建JList放入画面上,就完成了.

Sun官方还给了一个使用JList的例子,在同一行显示多个项目:

界面如下:

创建JList的过程和前一个例子相同,只是需要继承JList把它的getScrollableUnitIncrement方法重写,变成我们自己的表现样式:

   /**

     * Returns the distance to scroll to expose the next or previous

     * row (for vertical scrolling) or column (for horizontal scrolling).

     */

    @Override

publicint getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {

这个方法就是描绘JList前一个后一个行或者列的表现的,只需要根据容器的大小算出现在每个格子的大小:

 Rectangle r = getCellBounds(row, row);

然后依次放置就可以了,布局使用FlowLayout.

      Point loc = r.getLocation();

      loc.y--;

      int prevIndex = locationToIndex(loc);

      Rectangle prevR = getCellBounds(prevIndex, prevIndex);

      if (prevR == null || prevR.y >= r.y) {

            return 0;

      }

      return prevR.height;

当然也可以重写其它的类实现其它样式,复杂样式也可以重写JListListUI.

其它的JList的设置颜色,字体,背景等都很简单,按照API就可以了,至于拖拽操作也和其它组件一样.

最后我们实现一个自己的JList,在它的单元格内加入图片,复选框,设置它是否可以选择,图片是否可以显示,当然你也可以加入其它的表现形式,只需要再写入新的接口.

界面如下:




当单元格是选中状态时,点击Print按钮输入选中的项目:

工程目录如下:

先看几个接口,

/**

 * the interface that the JComboBox can Icon enable.

*/

publicinterface IconEnable {

/**

 * the interface that the list can have icon.

*/

publicinterface IconItem {

/**

 * the interface that the JComboBox can select enable.

*/

publicinterface SelectEnable {

/**

 * the interface that the list can have select.

*/

publicinterface SelectItem {

它们都提供

    /**

     * set bean.

     */

    publicvoid setXXX(XXX XXX);

    /**

     * get bean.

     */

    public XXX getXXX();

来表示JList某项自定义属性.

然后自定义一个类实现这些接口:

/**

 * list item.

*/

publicclass MyListItem implements IconItem, IconEnable, SelectEnable,

       SelectItem {

它的属性:

    /**

     * list value.

     */

    private Object listItem = null;

    /**

     * list is select.

     */

    privatebooleanisSelected = false;

    /**

     * list icon.

     */

    private Icon icon = null;

    /**

     * list icon enable.

     */

    privatebooleanisIconEnable = true;

    /**

     * list is select enable.

     */

    privatebooleanisSelectEnable = true;

这样就使这个类可以保存JList的单元格的项,我们的JListModel使用这个类的实例作为Bean来存储JList的信息.

接着是一个JList项目的显示描绘类,

/**

 * the list cell's label.

*/

publicclass MyListLabel extends JLabel {

它复写JLabel

    @Override

    publicvoid setBackground(Color color) {

    @Override

    publicvoid paint(Graphics g) {

    @Override

    public Dimension getPreferredSize() {

调整JList的单元格的颜色,图片样式,字体,焦点偏移和最适合大小.

g.setColor(UIManager.getColor("Tree.textBackground"));

g.drawRect(imageOffset, 0, d.width - 1 - imageOffset,

                         d.height - 1);

最后就是重要的画面表现类MyListRenderer,它需要实现ListCellRenderer接口

/**

 * JList cell renderer.

*/

publicclass MyListRenderer extends JPanel implements MouseListener,

       ListCellRenderer {

通过继承JPanel,使JList的单元格可以实现任何的控件效果,这里是放置一个JCheckBox和我们自定义的MyListLabel:

    /**

     * JList cell renderer.

     */

    public MyListRenderer(JList list) {

       this.list = list;

       setLayout(null);

       add(checkBox = new JCheckBox());

       add(label = new MyListLabel());

    checkBox.setBackground(UIManager.getColor("Tree.textBackground"));

    label.setForeground(UIManager.getColor("Tree.textForeground"));

       commonIcon = UIManager.getIcon("Tree.leafIcon");

    }

实现接口的getListCellRendererComponent方法,返回我们需要的呈现:

    /**

     * Return a component that has been configured to display the specified

     * value.

     */

    @Override

    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {

其中value就是我们的自定义单元格MyListItem,可以设置属性:

设置可用: setEnabled(((SelectEnable) value).isSelectEnabled());

设置选择: checkBox.setSelected(((SelectItem) value).getSelect());

设置Label的选择: label.setSelected(isSelected);

设置字体和图片:

label.setFont(list.getFont());

       label.setText(value.toString());

       label.setFocus(cellHasFocus);

       if (((IconEnable) value).isIconEnabled()) {

           Icon icon = ((IconItem) value).getIcon();

           if (icon == null) {

              icon = commonIcon;

           }

           label.setIcon(icon);

       }

同样也通过重写getPreferredSizesetBackgrounddoLayout设置合适大小、颜色和布局:

Dimension d_check = checkBox.getPreferredSize();

       Dimension d_label = label.getPreferredSize();

       returnnew Dimension(d_check.width + d_label.width,

              (d_check.height < d_label.height ? d_label.height

                     : d_check.height));

通过两个组件的合适大小可以得出两个组件的位置:

y_check = (d_label.height - d_check.height) / 2;

然后通过设定位置,做出Layout:

label.setLocation(d_check.width, y_label);

label.setBounds(d_check.width, y_label, d_label.width, d_label.height);

最后处理的是JList的鼠标选择JCheckBox事件,

    @Override

    publicvoid mouseClicked(MouseEvent e) {

通过选择定位选择的Item,然后对应设置选中状态,刷新:

    int index = list.locationToIndex(e.getPoint());

    MyListItem item = (MyListItem) list.getModel().getElementAt(index);

    if (((SelectEnable) item).isSelectEnabled()) {

       item.setSelect(!((SelectItem) item).getSelect());

       Rectangle rect = list.getCellBounds(index, index);

       ist.repaint(rect);

    }

这个我们的JList就设置完了,它的使用和普通的一样,只不过Model使用的是MyListItem数组:

    MyListItem[] items = { new MyListItem("Astart"),

           new MyListItem("B-BIX", true, icon),

           new MyListItem("have fun game!", false, null, false, false),

           new MyListItem("郁闷", false),

           new MyListItem("abc", true),

           new MyListItem("12867831", false, icon),

           new MyListItem("happy", false, null, false, true),

           new MyListItem("defINE", false, null) };

JList jList = new JList(items);

设置Renderer:

jList.setCellRenderer(new MyListRenderer(jList));

然后得到的JList就和普通JComponent一样使用了.

posted on 2010-05-03 22:46 zeyuphoenix 阅读(36220) 评论(0)  编辑  收藏 所属分类: Java基本组件的使用

导航

<2010年5月>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

统计

常用链接

留言簿(52)

随笔分类

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜