<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://www.tkk7.com/zeyuphoenix/archive/2010/05/03/319976.html
    jlist是比較簡單的組件,基本不用考慮ui的問題,比jtable和jtree好處理,也沒什么高級(jí)擴(kuò)展

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


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 精品一区二区三区高清免费观看 | 亚洲午夜国产精品无码| 亚洲无码黄色网址| 亚洲AV午夜成人片| 亚洲一区二区三区深夜天堂 | 国产91成人精品亚洲精品| 国产精品小视频免费无限app| 久爱免费观看在线网站| 黄色成人网站免费无码av| 四虎影永久在线高清免费| 狠狠色伊人亚洲综合成人| 亚洲喷奶水中文字幕电影| 天天综合亚洲色在线精品| 精品人妻系列无码人妻免费视频 | 91在线视频免费看| 亚洲片国产一区一级在线观看 | 最近中文字幕2019高清免费| 国产视频精品免费| 亚洲成a人片在线观看无码专区| 自拍日韩亚洲一区在线| 一个人看的hd免费视频| 2022年亚洲午夜一区二区福利| 亚洲综合激情五月丁香六月| 一本大道一卡二大卡三卡免费| 中文字幕免费视频| 亚洲AV无码一区二区三区在线观看| 久久精品国产亚洲香蕉| 亚洲av永久无码| 日韩内射激情视频在线播放免费| 国产精品冒白浆免费视频| 午夜亚洲www湿好大| 女bbbbxxxx另类亚洲| 欧洲一级毛片免费| 久久久久亚洲爆乳少妇无| 亚洲欧洲另类春色校园网站| 一级成人生活片免费看| 一个人免费高清在线观看| 亚洲精品无码久久久久sm| 亚洲精品无码中文久久字幕| 亚欧免费一级毛片| 亚洲国产黄在线观看|