类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);
}
}