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

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

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

    TWaver - 專注UI技術

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

    Swing探秘:編寫一個JCheckListBox組件

    Posted on 2010-08-23 13:56 TWaver 閱讀(2037) 評論(1)  編輯  收藏

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

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

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

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

      1import java.awt.*;
      2import java.awt.event.*;
      3import javax.swing.*;
      4import javax.swing.event.*;
      5
      6public class JCheckListBox extends JList {
      7    //這個boolean數組裝載所有item是否被check的信息。
      8
      9    private boolean[] checkedItems = null;
     10
     11    /**
     12     * 定義一個簡單的ListModel,它可以發送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     * 這里就覆蓋了一個構造函數。其他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數組、安裝一個渲染器、安裝一個鼠標監聽器。
     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                //這點代碼基本上從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                //雖然抄襲,可這里別忘了設置check信息。
     86                this.setSelected(isChecked(index));
     87                return this;
     88            }

     89        }

     90
     91        this.setCellRenderer(new MyCellRenderer());
     92        //定義一個鼠標監聽器。如果點擊某個item,翻轉其check狀態。
     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     * 翻轉指定item的check狀態。
    107     * @param index int
    108     */

    109    public void invertChecked(int index) {
    110        checkedItems[index] = !checkedItems[index];
    111        //別忘了發送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個數
    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索引的數組。
    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中文社區之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("當前沒有選擇。");
    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("當前沒有選擇。");
    184                }
     else {
    185                    String text = "當前選擇:";
    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}

    運行效果如下圖:


    評論

    # re: Swing探秘:編寫一個JCheckListBox組件  回復  更多評論   

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

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 亚欧乱色国产精品免费视频| 无码欧精品亚洲日韩一区夜夜嗨| 亚洲日韩在线观看免费视频| 色偷偷女男人的天堂亚洲网| 亚洲精品成人片在线播放 | 亚洲线精品一区二区三区| 毛片免费视频在线观看| 午夜视频免费在线观看| 久青草视频在线观看免费| 美女黄频a美女大全免费皮| 亚洲AV成人一区二区三区在线看| 亚洲欧洲国产精品你懂的| 亚洲香蕉成人AV网站在线观看| 国产精品国产午夜免费福利看| 国产91免费视频| 无码av免费一区二区三区| 9久热这里只有精品免费| 婷婷亚洲综合五月天小说在线 | 在线观看免费人成视频色9| 久久福利青草精品资源站免费| 一级毛片免费播放试看60分钟| 亚洲AV无码XXX麻豆艾秋| 午夜在线a亚洲v天堂网2019| 亚洲的天堂av无码| 亚洲美女aⅴ久久久91| 亚洲美女人黄网成人女| 亚洲精品中文字幕无乱码| 亚洲精品影院久久久久久| 精品亚洲成a人片在线观看少妇| 亚洲国产精品人久久| 亚洲电影中文字幕| 91天堂素人精品系列全集亚洲 | 中文字幕视频在线免费观看| 在线播放国产不卡免费视频| 一本一道dvd在线观看免费视频| 黄色三级三级三级免费看| 免费人成大片在线观看播放电影 | 精品免费久久久久久成人影院| 成人特黄a级毛片免费视频| 在线看片人成视频免费无遮挡| 成人免费看片又大又黄|