JComboBox 实现多选

类ComboCheckBoxEntry,用于保存JComboBoxde item信息
public class ComboCheckBoxEntry {

    boolean checked;
    boolean state;
    String uniqueCode;
    String value;

    public ComboCheckBoxEntry() {
        this.checked = false;
        this.state = true;
        this.uniqueCode = "-1";
        this.value = "Empty Entry";
    }

    public ComboCheckBoxEntry(String uniqueCode, String value) {
        this.checked = false;
        this.state = true;
        this.uniqueCode = uniqueCode;
        this.value = value;
    }

    public ComboCheckBoxEntry(boolean checked, String uniqueCode, String value) {
        this.checked = checked;
        this.state = true;
        this.uniqueCode = uniqueCode;
        this.value = value;
    }

    public ComboCheckBoxEntry(boolean checked, boolean state, String uniqueCode, String value) {
        this.checked = checked;
        this.state = state;
        this.uniqueCode = uniqueCode;
        this.value = value;
    }

    public boolean getChecked() {
        return checked;
    }

    public void setChecked(boolean checked) {
        this.checked = checked;
    }

    public String getUniqueCode() {
        return uniqueCode;
    }

    public String getValue() {
        return value;
    }

    public boolean getState() {
        return state;
    }
}

自定义render ComboCheckBoxRenderer
public class ComboCheckBoxRenderer extends JCheckBox implements ListCellRenderer, Serializable {

    protected static Border noFocusBorder;

    public ComboCheckBoxRenderer() {
        super();
        if (noFocusBorder == null) {
            noFocusBorder = new EmptyBorder(1, 1, 1, 1);
        }
        setOpaque(true);
        setBorder(noFocusBorder);
    }

    public Component getListCellRendererComponent(
            JList list,
            Object value,
            int index,
            boolean isSelected,
            boolean cellHasFocus) {
        setComponentOrientation(list.getComponentOrientation());
        if (isSelected) {
            setBackground(list.getSelectionBackground());
            setForeground(list.getSelectionForeground());
        } else {
            setBackground(list.getBackground());
            setForeground(list.getForeground());
        }

        if (value instanceof ComboCheckBoxEntry) {
            ComboCheckBoxEntry item = (ComboCheckBoxEntry) value;
            setSelected(item.getChecked());
            setToolTipText(item.getValue());
            setText(item.getValue());
        } else {
            setText((value == null) ? "" : value.toString());
        }

        setEnabled(list.isEnabled());
        setFont(list.getFont());
        setBorder((cellHasFocus) ? UIManager.getBorder("List.focusCellHighlightBorder") : noFocusBorder);

        return this;
    }
}

重写UI和POPUP ComboCheckBoxUI
public class ComboCheckBoxUI extends MetalComboBoxUI {

    private boolean isMultiSel = false;
    public int maxWidth = 300;

    public ComboCheckBoxUI() {
    }

    public ComboCheckBoxUI(int maxWidth) {
        this.maxWidth = maxWidth;
    }

    public static ComponentUI createUI(JComponent c) {
        return new ComboCheckBoxUI();
    }

    @Override
    protected ComboPopup createPopup() {
        ComboCheckPopUp popUp = new ComboCheckPopUp(comboBox, maxWidth);
        popUp.getAccessibleContext().setAccessibleParent(comboBox);
        return popUp;
    }

    public class ComboCheckPopUp extends BasicComboPopup {

        private int width = -1;
        private int maxWidth = 300;

        public ComboCheckPopUp(JComboBox cBox, int maxWidth) {
            super(cBox);
            this.maxWidth = maxWidth;
        }

        @Override
        protected JScrollPane createScroller() {
            return new JScrollPane(
                    list,
                    ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
                    ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        }

        @Override
        protected MouseListener createListMouseListener() {
            return new CheckBoxListMouseHandler();
        }

        @Override
        protected KeyListener createKeyListener() {
            return new CheckBoxKeyHandler();
        }

        @Override
        public void show() {

            Dimension popupSize = comboBox.getSize();
            Insets insets = getInsets();
            popupSize.setSize(popupSize.width - (insets.right + insets.left),
                    getPopupHeightForRowCount(comboBox.getMaximumRowCount()));

            int maxWidthOfCell = calcPreferredWidth();
            width = maxWidthOfCell;

            if (comboBox.getItemCount() > comboBox.getMaximumRowCount()) {
                width += scroller.getVerticalScrollBar().getPreferredSize().width;
            }

            if (width > this.maxWidth) {
                width = this.maxWidth;
            }

            if (width < this.comboBox.getWidth()) {
                width = this.comboBox.getWidth();
            }

            if (maxWidthOfCell > width) {
                popupSize.height += scroller.getHorizontalScrollBar().getPreferredSize().height;
            }

            Rectangle popupBounds = computePopupBounds(0, comboBox.getBounds().height, width, popupSize.height);
            scroller.setMaximumSize(popupBounds.getSize());
            scroller.setPreferredSize(popupBounds.getSize());
            scroller.setMinimumSize(popupBounds.getSize());
            list.invalidate();
            syncListSelectionWithComboBoxSelection();
            list.ensureIndexIsVisible(list.getSelectedIndex());
            setLightWeightPopupEnabled(comboBox.isLightWeightPopupEnabled());
            show(comboBox, popupBounds.x, popupBounds.y);
        }

        private int calcPreferredWidth() {
            int prefferedWidth = 0;
            ListCellRenderer renderer = list.getCellRenderer();
            for (int index = 0, count = list.getModel().getSize(); index < count; index++) {
                Object element = list.getModel().getElementAt(index);
                Component comp = renderer.getListCellRendererComponent(list, element, index, false,
                        false);
                Dimension dim = comp.getPreferredSize();
                if (dim.width > prefferedWidth) {
                    prefferedWidth = dim.width;
                }
            }
            return prefferedWidth;
        }

        void syncListSelectionWithComboBoxSelection() {
            int selectedIndex = comboBox.getSelectedIndex();
            if (selectedIndex == -1) {
                list.clearSelection();
            } else {
                list.setSelectedIndex(selectedIndex);
            }
        }

        public void setPopupWidth(int width) {
            this.width = width;
        }

        protected class CheckBoxKeyHandler extends KeyAdapter {

            @Override
            public void keyPressed(KeyEvent e) {
                isMultiSel = e.isControlDown();
            }

            @Override
            public void keyReleased(KeyEvent e) {
                isMultiSel = e.isControlDown();
            }
        }

        protected class CheckBoxListMouseHandler extends MouseAdapter {

            @Override
            public void mousePressed(MouseEvent anEvent) {
                int index = list.getSelectedIndex();
                ComboCheckBoxEntry item = (ComboCheckBoxEntry) list.getModel().getElementAt(index);
                boolean checked = !item.getChecked();
                int size = list.getModel().getSize();

                if (isMultiSel) {
                    item.setChecked(checked);
                } else {
                    for (int i = 0; i < size; i++) {
                        ComboCheckBoxEntry ccbe = (ComboCheckBoxEntry) list.getModel().getElementAt(i);
                        ccbe.setChecked(false);
                    }
                    item.setChecked(true);
                }
                updateListBoxSelectionForEvent(anEvent, false);
                Rectangle rect = list.getCellBounds(0, size - 1);
                list.repaint(rect);
            }

            @Override
            public void mouseReleased(MouseEvent anEvent) {
                if (!isMultiSel) {
                    ComboCheckBoxEntry item = (ComboCheckBoxEntry) list.getSelectedValue();
                    if (item.checked) {
                        comboBox.setSelectedIndex(list.getSelectedIndex());
                        comboBox.setPopupVisible(false);
                    }
                }
            }
        }
    }
}
重写 JComboBox 以及测试
public class JComboCheckBox extends JComboBox {

    private int maxWidth = 300;

    public JComboCheckBox() {
        super();
        setRenderer(new ComboCheckBoxRenderer());
        updateUI();
    }

    public JComboCheckBox(String[] items) {
        super();
        setRenderer(new ComboCheckBoxRenderer());
        addItems(items);
        updateUI();
    }

    public JComboCheckBox(Vector<String> items) {
        super();
        setRenderer(new ComboCheckBoxRenderer());
        addItems(items.toArray(new String[0]));
        updateUI();
    }

    public JComboCheckBox(int maxWidth) {
        super();
        this.maxWidth = maxWidth;
        setRenderer(new ComboCheckBoxRenderer());
        updateUI();
    }

    public JComboCheckBox(String[] items, int maxWidth) {
        super();
        this.maxWidth = maxWidth;
        setRenderer(new ComboCheckBoxRenderer());
        addItems(items);
        updateUI();
    }

    public JComboCheckBox(Vector<String> items, int maxWidth) {
        super();
        this.maxWidth = maxWidth;
        setRenderer(new ComboCheckBoxRenderer());
        addItems(items.toArray(new String[0]));
        updateUI();
    }

    public void addItems(String[] items) {
        for (int i = 0; i < items.length; i++) {
            String string = items[i];
            this.addItem(new ComboCheckBoxEntry(String.valueOf(i + 1), string));
        }
    }

    public void addItem(ComboCheckBoxEntry item) {
        super.addItem(item);
    }

    public void addItem(boolean checked, boolean state, String id, String value) {
        super.addItem(new ComboCheckBoxEntry(checked, state, id, value));
    }

    public String[] getCheckedCodes() {
        Vector values = new Vector();
        DefaultComboBoxModel model = (DefaultComboBoxModel) getModel();
        for (int i = 0; i < model.getSize(); i++) {
            ComboCheckBoxEntry item = (ComboCheckBoxEntry) model.getElementAt(i);
            boolean checked = item.getChecked();
            if (checked) {
                values.add(item.getUniqueCode());
            }
        }
        String[] retVal = new String[values.size()];
        values.copyInto(retVal);
        return retVal;
    }

    public String[] getCheckedValues() {
        Vector values = new Vector();
        DefaultComboBoxModel model = (DefaultComboBoxModel) getModel();
        for (int i = 0; i < model.getSize(); i++) {
            ComboCheckBoxEntry item = (ComboCheckBoxEntry) model.getElementAt(i);
            boolean checked = item.getChecked();
            if (checked) {
                values.add(item.getValue());
            }
        }
        String[] retVal = new String[values.size()];
        values.copyInto(retVal);
        return retVal;
    }

    @Override
    public void updateUI() {
        setUI(new ComboCheckBoxUI(maxWidth));
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setSize(650, 580);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel jPanel = new JPanel();

        String[] values = new String[]{"1111111111111111111", "22", "33333333333333333333", 
"4444444444444", "55555555555555555", "6", "77", "6", "77", "6", "77"};
        final JComboCheckBox checkBox = new JComboCheckBox(values);

        checkBox.setPreferredSize(new Dimension(150, 30));
        jPanel.add(checkBox);

        JButton btnCode = new JButton("Code");
        btnCode.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                for (String string : checkBox.getCheckedCodes()) {
                    System.out.print(string + " ");
                }
                System.out.println("");
            }
        });
        jPanel.add(btnCode);

        JButton btnValue = new JButton("Value");
        btnValue.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                for (String string : checkBox.getCheckedValues()) {
                    System.out.print(string + " ");
                }
                System.out.println("");
            }
        });
        jPanel.add(btnValue);

        frame.getContentPane().add(jPanel);
        frame.setVisible(true);
    }
}

posted on 2010-08-26 17:10  alanzyy  阅读(1735)  评论(1编辑  收藏  举报

导航