<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    TWaver - 專注UI技術(shù)

    http://twaver.servasoft.com/
    posts - 171, comments - 191, trackbacks - 0, articles - 2
      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    記得Delphi里面有一個(gè)TCheckListBox控件,是一個(gè)可打勾的列表。但是這個(gè)東西在Swing里面并沒有現(xiàn)成的。如今,我們就一起動(dòng)手制作一個(gè)。根據(jù)Java的管理,就叫JCheckListBox吧。

    寫代碼之前,先考慮以下問題:

    • 繼承:當(dāng)然是從Swing的JList繼承。
    • 數(shù)據(jù)擴(kuò)充:對(duì)于JList來說,它是顯示了一系列Object。無論其類型如何,都用一個(gè)默認(rèn)的渲染器(DefaultListCellRenderer,從JLabel繼承而來)來畫,每個(gè)條目的文字用Object.toString()來設(shè)置。但是對(duì)于JCheckListBox來說,除了顯示文本外,還要考慮每個(gè)條目是否被選中,如果選中,要顯示“打勾”。所以,JList需要維護(hù)“每一個(gè)條目是否選中”的狀態(tài)信息。我們放在一個(gè)boolean數(shù)組中。
    • 渲染器:默認(rèn)的Renderer肯定是不行了,無法顯示打勾。自然想到用JCheckBox來重新做一個(gè)渲染器,設(shè)置到JCheckListBox中。
    • 鼠標(biāo)監(jiān)聽器:現(xiàn)在可以畫每個(gè)條目了,但還不夠,必須能響應(yīng)鼠標(biāo)的點(diǎn)擊以便Check/UnCheck才行。所以要在JCheckListBox上加一個(gè)鼠標(biāo)監(jiān)聽器來響應(yīng)鼠標(biāo)事件。當(dāng)然,如果你想讓它相應(yīng)鍵盤輸入(例如Ctrl+A全選)也可如法炮制。
    • CheckListBoxModel:為了操作方便,這里還從AbstractListModel擴(kuò)充一個(gè)CheckListBoxModel,它能在條目Check變化時(shí)發(fā)送事件。

    好了,由于代碼和原理都比較簡單,不再贅述,直接給出代碼,以及簡單注釋。

      1import java.awt.*;
      2import java.awt.event.*;
      3import javax.swing.*;
      4import javax.swing.event.*;
      5
      6public class JCheckListBox extends JList {
      7    //這個(gè)boolean數(shù)組裝載所有item是否被check的信息。
      8
      9    private boolean[] checkedItems = null;
     10
     11    /**
     12     * 定義一個(gè)簡單的ListModel,它可以發(fā)送check變化事件。
     13     */

     14    class CheckListBoxModel extends AbstractListModel {
     15
     16        private Object[] items = null;
     17
     18        CheckListBoxModel(Object[] items) {
     19            this.items = items;
     20        }

     21
     22        public int getSize() {
     23            return items.length;
     24        }

     25
     26        public Object getElementAt(int i) {
     27            return items[i];
     28        }

     29
     30        protected void fireCheckChanged(Object source, int index) {
     31            fireContentsChanged(source, index, index);
     32        }

     33
     34        public Object getItem(int index) {
     35            return items[index];
     36        }

     37    }

     38
     39    /**
     40     * 這里就覆蓋了一個(gè)構(gòu)造函數(shù)。其他JList你自己覆蓋吧,反正super一下再init就OK了。
     41     * @param items Object[]
     42     */

     43    public JCheckListBox(Object[] items) {
     44        setModel(new CheckListBoxModel(items));
     45        init();
     46    }

     47
     48    /**
     49     * 初始化控件。包括初始化boolean數(shù)組、安裝一個(gè)渲染器、安裝一個(gè)鼠標(biāo)監(jiān)聽器。
     50     */

     51    protected void init() {
     52        checkedItems = new boolean[this.getModel().getSize()];
     53        class MyCellRenderer extends JCheckBox implements ListCellRenderer {
     54
     55            public MyCellRenderer() {
     56                setOpaque(true);
     57            }

     58
     59            public Component getListCellRendererComponent(
     60                    JList list,
     61                    Object value,
     62                    int index,
     63                    boolean isSelected,
     64                    boolean cellHasFocus) {
     65                //這點(diǎn)代碼基本上從DefaultListCellRenderer.java中抄襲的。
     66                setComponentOrientation(list.getComponentOrientation());
     67                if (isSelected) {
     68                    setBackground(list.getSelectionBackground());
     69                    setForeground(list.getSelectionForeground());
     70                }
     else {
     71                    setBackground(list.getBackground());
     72                    setForeground(list.getForeground());
     73                }

     74
     75                if (value instanceof Icon) {
     76                    setIcon((Icon) value);
     77                    setText("");
     78                }
     else {
     79                    setIcon(null);
     80                    setText((value == null? "" : value.toString());
     81                }

     82                setEnabled(list.isEnabled());
     83                setFont(list.getFont());
     84
     85                //雖然抄襲,可這里別忘了設(shè)置check信息。
     86                this.setSelected(isChecked(index));
     87                return this;
     88            }

     89        }

     90
     91        this.setCellRenderer(new MyCellRenderer());
     92        //定義一個(gè)鼠標(biāo)監(jiān)聽器。如果點(diǎn)擊某個(gè)item,翻轉(zhuǎn)其check狀態(tài)。
     93        class CheckBoxListener extends MouseAdapter {
     94
     95            @Override
     96            public void mouseClicked(MouseEvent e) {
     97                int index = locationToIndex(e.getPoint());
     98                invertChecked(index);
     99            }

    100        }

    101
    102        this.addMouseListener(new CheckBoxListener());
    103    }

    104
    105    /**
    106     * 翻轉(zhuǎn)指定item的check狀態(tài)。
    107     * @param index int
    108     */

    109    public void invertChecked(int index) {
    110        checkedItems[index] = !checkedItems[index];
    111        //別忘了發(fā)送event。
    112        CheckListBoxModel model = (CheckListBoxModel) getModel();
    113        model.fireCheckChanged(this, index);
    114        this.repaint();
    115    }

    116
    117    /**
    118     * 是否指定item被check。
    119     * @param index int
    120     * @return boolean
    121     */

    122    public boolean isChecked(int index) {
    123        return checkedItems[index];
    124    }

    125
    126    /**
    127     * 獲得選中的item個(gè)數(shù)
    128     */

    129    public int getCheckedCount() {
    130        int result = 0;
    131        for (int i = 0; i < checkedItems.length; i++{
    132            if (checkedItems[i]) {
    133                result++;
    134            }

    135        }

    136        return result;
    137    }

    138
    139    /**
    140     * 所有選中item索引的數(shù)組。
    141     */

    142    public int[] getCheckedIndices() {
    143        int[] result = new int[getCheckedCount()];
    144        int index = 0;
    145        for (int i = 0; i < checkedItems.length; i++{
    146            if (checkedItems[i]) {
    147                result[index] = i;
    148                index++;
    149            }

    150        }

    151        return result;
    152    }

    153
    154    public static void main(String[] args) throws Exception {
    155
    156        Font font = new Font("微軟雅黑", Font.PLAIN, 12);
    157
    158        JFrame frame = new JFrame("TWaver中文社區(qū)之Swing探秘");
    159
    160        final JCheckListBox list = new JCheckListBox(new Object[]{"張三""李四""王二麻子""木頭六","小七子"});
    161        list.setFont(font);
    162        frame.getContentPane().add(new JScrollPane(list), BorderLayout.CENTER);
    163        JButton button = new JButton("OK");
    164        button.addActionListener(new ActionListener() {
    165
    166            public void actionPerformed(ActionEvent e) {
    167                System.exit(0);
    168            }

    169        }
    );
    170        frame.getContentPane().add(button, BorderLayout.SOUTH);
    171        final JLabel label = new JLabel("當(dāng)前沒有選擇。");
    172        label.setFont(font);
    173        list.getModel().addListDataListener(new ListDataListener() {
    174
    175            public void intervalAdded(ListDataEvent e) {
    176            }

    177
    178            public void intervalRemoved(ListDataEvent e) {
    179            }

    180
    181            public void contentsChanged(ListDataEvent e) {
    182                if (list.getCheckedCount() == 0{
    183                    label.setText("當(dāng)前沒有選擇。");
    184                }
     else {
    185                    String text = "當(dāng)前選擇:";
    186                    int[] indices = list.getCheckedIndices();
    187                    for (int i = 0; i < indices.length; i++{
    188                        text += ((CheckListBoxModel) list.getModel()).getItem(indices[i]).toString() + ",";
    189                    }

    190                    label.setText(text);
    191                }

    192            }

    193        }
    );
    194        frame.getContentPane().add(label, BorderLayout.NORTH);
    195        frame.setBounds(300300400200);
    196        frame.setVisible(true);
    197    }

    198}

    運(yùn)行效果如下圖:


    評(píng)論

    # re: Swing探秘:編寫一個(gè)JCheckListBox組件  回復(fù)  更多評(píng)論   

    2010-08-24 09:25 by zeyuphoenix
    恩 以前我也寫過一個(gè)
    http://m.tkk7.com/zeyuphoenix/archive/2010/05/03/319976.html
    jlist是比較簡單的組件,基本不用考慮ui的問題,比jtable和jtree好處理,也沒什么高級(jí)擴(kuò)展

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 国产l精品国产亚洲区在线观看| 免费观看的av毛片的网站| 亚洲一区二区三区偷拍女厕| 无人视频在线观看免费播放影院| 国产又大又粗又硬又长免费| 狼人大香伊蕉国产WWW亚洲| 日韩毛片免费在线观看| 色吊丝免费观看网站| 亚洲午夜AV无码专区在线播放| 一级毛片视频免费观看| 色噜噜亚洲精品中文字幕| 你懂得的在线观看免费视频| 亚洲av无码乱码国产精品 | 羞羞漫画登录页面免费| 亚洲国产一区视频| 国产成人免费AV在线播放| 久久亚洲精品无码aⅴ大香| 天天影视色香欲综合免费| 亚洲性色精品一区二区在线| 永久在线毛片免费观看| 男女啪啪免费体验区| 国产精品亚洲а∨无码播放| 久久99国产乱子伦精品免费| 最新国产精品亚洲| 亚洲国产精品13p| 日本免费在线中文字幕| 亚洲AV男人的天堂在线观看| 国产又大又长又粗又硬的免费视频 | 亚洲伊人久久大香线蕉在观 | 在线免费观看色片| 香蕉视频在线观看免费| 亚洲国产精品成人精品无码区 | 男性gay黄免费网站| 国产亚洲婷婷香蕉久久精品| 999在线视频精品免费播放观看| 亚洲AV无码国产一区二区三区| 久久亚洲高清综合| 亚洲成人免费网站| 欧洲美女大片免费播放器视频| 亚洲第一精品福利| 国产伦精品一区二区三区免费迷|