package com.fr.design.gui.ilist; import java.awt.BorderLayout; import java.awt.Component; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Arrays; import java.util.EventListener; import java.util.List; import javax.swing.JComponent; import javax.swing.JList; import javax.swing.ListCellRenderer; import javax.swing.ListModel; import javax.swing.ListSelectionModel; import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; import com.fr.design.gui.icheckbox.UICheckBox; import com.fr.stable.StringUtils; /** * CheckBoxs + JList. */ public class CheckBoxList extends JComponent { /** * 选择状态----全选和全不选 * * @editor zhou * @since 2012-4-1下午2:39:10 */ public static enum SelectedState { ALL, NONE } private boolean[] selects; private JList jlist; private UICheckBox chooseAll; public CheckBoxList(Object[] items) { this(items, SelectedState.NONE, StringUtils.EMPTY); } public CheckBoxList(Object[] items, String name) { this(items, SelectedState.NONE, name); } /** * Class constructor. * * @param items * Items with which to populate the list. * @param default_state * default state, true or false */ public CheckBoxList(Object[] items, SelectedState state, String name) { jlist = new BOXLIST(items); jlist.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); this.selects = new boolean[items.length]; boolean default_state = (state == SelectedState.ALL); Arrays.fill(this.selects, default_state); jlist.setCellRenderer(new CheckListCellRenderer()); jlist.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { doCheck(); } public void mouseReleased(MouseEvent e) { doCheck(); } }); jlist.addKeyListener(new KeyAdapter() { @Override public void keyTyped(KeyEvent e) { if (e.getKeyChar() == ' ') { doCheck(); } } }); this.setLayout(new BorderLayout()); chooseAll = new UICheckBox(name, default_state); chooseAll.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (chooseAll.isSelected()) { setSelected(true); } else { setSelected(false); } } }); this.add(chooseAll, BorderLayout.NORTH); this.add(jlist, BorderLayout.CENTER); } /* * 用于CellRenderer显示value为text */ protected String value2Text(Object value) { return value != null ? value.toString() : StringUtils.EMPTY; } public void setItems(Object[] os) { if (os == null) { this.setSelected(false); } else { for (int i = 0, len = os.length; i < len; i++) { Object o = os[i]; for (int j = 0, jen = jlist.getModel().getSize(); j < jen; j++) { if (o.equals(jlist.getModel().getElementAt(j))) { this.setSelected(j, true); } } } } this.repaint(); } /** * Is selected */ public boolean isSelected(int index) { if (selects == null || index >= selects.length) { return false; } return selects[index]; } public void setSelected(int index, boolean isSelected) { if (selects == null || index >= selects.length) { return; } selects[index] = isSelected; this.repaint(this.getBounds()); this.fireCheckBoxListSelectionChangeListener(); } private void setSelected(boolean isSelected) { if (selects == null) { return; } for (int i = 0; i < selects.length; i++) { selects[i] = isSelected; } this.repaint(this.getBounds()); this.fireCheckBoxListSelectionChangeListener(); } /** * Returns an array of the objects that have been selected. Overrides the * JList method. */ public Object[] getSelectedValues() { return this.jlist.getSelectedValues(); } private class BOXLIST extends JList { public BOXLIST(Object[] items) { super(items); } @Override protected void processMouseEvent(MouseEvent e) { if (e.getX() < 20) { if (e.isControlDown() || e.isAltDown() || e.isShiftDown() || e.isMetaDown()) { int[] indices = getSelectedIndices(); if (indices.length == 0) { super.processMouseEvent(e); } } else { super.processMouseEvent(e); } } else { super.processMouseEvent(e); } int id = e.getID(); switch (id) { case MouseEvent.MOUSE_PRESSED: break; case MouseEvent.MOUSE_RELEASED: break; case MouseEvent.MOUSE_CLICKED: doCheck(); break; case MouseEvent.MOUSE_EXITED: break; case MouseEvent.MOUSE_ENTERED: break; } } @Override protected void processMouseMotionEvent(MouseEvent e) { if (e.getX() < 20) { return; } super.processMouseEvent(e); } @Override public Object[] getSelectedValues() { List list = new ArrayList(selects.length); for (int i = 0; i < selects.length; i++) { if (selects[i]) { list.add(this.getModel().getElementAt(i)); } } return list.toArray(); } } private void doCheck() { // p:这里必须改变所有选择checkbox. int index = jlist.getSelectedIndex(); boolean sValue = !selects[index]; // p:开始设置所有选择的checkbox. int[] indices = jlist.getSelectedIndices(); for (int i = 0; i < indices.length; i++) { setSelected(indices[i], sValue); } for (boolean selected : selects) { if (!selected) { chooseAll.setSelected(false); return; } } chooseAll.setSelected(true); repaint(); } private static final Border noFocusBorder = new EmptyBorder(1, 1, 1, 1); private class CheckListCellRenderer extends UICheckBox implements ListCellRenderer { public CheckListCellRenderer() { this.setOpaque(true); this.setBorder(noFocusBorder); } public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { this.setText(value2Text(value)); this.setSelected(selects[index]); this.setFont(list.getFont()); if (isSelected) { this.setBackground(list.getSelectionBackground()); this.setForeground(list.getSelectionForeground()); } else { this.setBackground(list.getBackground()); this.setForeground(list.getForeground()); } if (cellHasFocus) { this.setBorder(UIManager.getBorder("List.focusCellHighlightBorder")); } else { this.setBorder(noFocusBorder); } return this; } } public void addCheckBoxListSelectionChangeListener(CheckBoxListSelectionChangeListener l) { this.listenerList.add(CheckBoxListSelectionChangeListener.class, l); } public void removeCheckBoxListSelectionChangeListener(CheckBoxListSelectionChangeListener l) { this.listenerList.remove(CheckBoxListSelectionChangeListener.class, l); } public void fireCheckBoxListSelectionChangeListener() { // Guaranteed to return a non-null array Object[] listeners = listenerList.getListenerList(); // Process the listeners last to first, notifying // those that are interested in this event for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == CheckBoxListSelectionChangeListener.class) { ((CheckBoxListSelectionChangeListener)listeners[i + 1]).selectionChanged(this); } } } public static interface CheckBoxListSelectionChangeListener extends EventListener { public void selectionChanged(CheckBoxList target); } public ListModel getModel() { return jlist.getModel(); } }