package org.japura.gui; import java.awt.Color; import java.awt.Dimension; import java.util.HashMap; import java.util.List; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JScrollPane; import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; import org.japura.gui.event.ListCheckListener; import org.japura.gui.event.ListEvent; import org.japura.gui.model.DefaultListCheckModel; import org.japura.gui.model.ListCheckModel; import org.japura.gui.renderer.CheckListRenderer; /** * ComboBox with Check items. * <P> * Copyright (C) 2010-2011 Carlos Eduardo Leite de Andrade * <P> * This library is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * <P> * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * <P> * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <A * HREF="www.gnu.org/licenses/">www.gnu.org/licenses/</A> * <P> * For more information, contact: <A HREF="www.japura.org">www.japura.org</A> * <P> * * @author Carlos Eduardo Leite de Andrade */ public class CheckComboBox extends AbstractComboBox{ private static final long serialVersionUID = 8289247356412690742L; public static final CheckState NONE = CheckState.NONE; public static final CheckState MULTIPLE = CheckState.MULTIPLE; public static final CheckState ALL = CheckState.ALL; private JScrollPane scrollPane; private CheckList checkList; private ListDataListener listDataListener; private ListCheckListener listCheckListener; private int visibleRowCount = 8; private HashMap<CheckState, String> texts; public CheckComboBox() { texts = new HashMap<CheckState, String>(); setRenderer(new CheckListRenderer()); setModel(new DefaultListCheckModel()); } public void setRenderer(CheckListRenderer renderer) { getCheckList().setCellRenderer(renderer); updateCellPanelWidth(); } public int getVisibleRowCount() { return visibleRowCount; } public void setVisibleRowCount(int visibleRowCount) { this.visibleRowCount = Math.max(3, visibleRowCount); getCheckList().setVisibleRowCount(getVisibleRowCount()); } @Override public void setPopupVisible(boolean visible) { if (visible) { if (getModel().getSize() > 0) { int rows = Math.min(getVisibleRowCount(), getModel().getSize()); getCheckList().setVisibleRowCount(rows); getCheckList().setPreferredSize(null); Dimension pSize = getCheckList().getPreferredSize(); Dimension dim = getSize(); if (pSize.width < dim.width) { getCheckList().setPreferredSize( new Dimension(dim.width, pSize.height)); } getPopup().show(this, 0, dim.height); } } else { getPopup().setVisible(false); } } @Override protected void unregisterEmbeddedComponent(JComponent oldEmbeddedComponent) { if (oldEmbeddedComponent instanceof BatchSelection) { BatchSelection bs = (BatchSelection) oldEmbeddedComponent; bs.unregisterModel(); } } @Override protected void registerEmbeddedComponent(JComponent newEmbeddedComponent) { if (newEmbeddedComponent instanceof BatchSelection) { BatchSelection bs = (BatchSelection) newEmbeddedComponent; bs.registerModel(getModel()); } } public void setModel(ListCheckModel model) { getCheckList().setModel(model); model.removeListDataListener(getListDataListener()); model.removeListCheckListener(getListCheckListener()); model.addListDataListener(getListDataListener()); model.addListCheckListener(getListCheckListener()); if (getEmbeddedComponent() != null) { JComponent comp = getEmbeddedComponent().getComponent(); unregisterEmbeddedComponent(comp); registerEmbeddedComponent(comp); } updateCellPanelWidth(); } public ListCheckModel getModel() { return getCheckList().getModel(); } protected void updateCellPanelWidth() { if (getPrototypeDisplayValue() != null) { getComboBox().setPrototypeDisplayValue(getPrototypeDisplayValue()); return; } String value = null; for (CheckState checkState : CheckState.values()) { String text = getTextFor(checkState); if (text != null) { if (value == null) { value = text; } else if (text.length() > value.length()) { value = text; } } } ListCheckModel m = getModel(); for (int i = 0; i < m.getSize(); i++) { String str = m.getElementAt(i).toString(); if (value == null) { value = str; } else if (str.length() > value.length()) { value = str; } } getComboBox().setPrototypeDisplayValue(value); } private CheckList getCheckList() { if (checkList == null) { checkList = new CheckList(); } return checkList; } private ListCheckListener getListCheckListener() { if (listCheckListener == null) { listCheckListener = new ListCheckListener() { @Override public void addCheck(ListEvent event) { updateComboBox(); } @Override public void removeCheck(ListEvent event) { updateComboBox(); } }; } return listCheckListener; } @Override protected void updateComboBox() { getComboBox().removeAllItems(); CheckListRenderer renderer = getCheckList().getCellRenderer(); List<Object> checkeds = getModel().getCheckeds(); int total = getModel().getSize(); if (total > 0) { if (checkeds.size() == 0 && texts.containsKey(CheckState.NONE)) { getComboBox().addItem(getTextFor(CheckState.NONE)); } else if (checkeds.size() == 1) { getComboBox().addItem(renderer.getText(checkeds.get(0))); } else if (checkeds.size() == total && texts.containsKey(CheckState.ALL)) { getComboBox().addItem(getTextFor(CheckState.ALL)); } else if (checkeds.size() > 1 && texts.containsKey(CheckState.MULTIPLE)) { getComboBox().addItem(getTextFor(CheckState.MULTIPLE)); } } } private ListDataListener getListDataListener() { if (listDataListener == null) { listDataListener = new ListDataListener() { @Override public void contentsChanged(ListDataEvent e) {} @Override public void intervalAdded(ListDataEvent e) { updateComboBox(); updateCellPanelWidth(); repaint(); } @Override public void intervalRemoved(ListDataEvent e) { updateComboBox(); updateCellPanelWidth(); repaint(); } }; } return listDataListener; } public String getTextFor(CheckState checkState) { if (checkState != null) { return texts.get(checkState); } return null; } public void removeTextFor(CheckState checkState) { if (checkState != null) { texts.remove(checkState); if (checkState.equals(NONE)) { updateComboBox(); } } } public void setTextFor(CheckState checkState, String text) { if (checkState == null) { return; } if (text == null) { text = ""; } texts.put(checkState, text); if (checkState.equals(NONE)) { updateComboBox(); } updateCellPanelWidth(); repaint(); } private JScrollPane getScrollPane() { if (scrollPane == null) { scrollPane = new JScrollPane(); scrollPane.setBorder(BorderFactory.createLineBorder(Color.black)); scrollPane.setViewportView(getCheckList()); } return scrollPane; } @Override protected JComponent getPopupComponent() { return getScrollPane(); } public static enum CheckState { NONE, ALL, MULTIPLE; } }