com.jidesoft.swing.CheckBoxList Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jide-oss Show documentation
Show all versions of jide-oss Show documentation
JIDE Common Layer (Professional Swing Components)
/*
* @(#)CheckBoxList.java 4/21/2005
*
* Copyright 2002 - 2005 JIDE Software Inc. All rights reserved.
*/
package com.jidesoft.swing;
import javax.swing.*;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.text.Position;
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.*;
import java.util.List;
/**
* CheckBoxList
is a special JList which uses JCheckBox as the list element. In addition to regular JList
* feature, it also allows you select any number of elements in the list by selecting the check boxes.
*
* To select an element, user can mouse click on the check box, or highlight the rows and press SPACE key to toggle the
* selections.
*
* We used cell renderer feature in JList to add the check box in each row. However you can still set your own cell
* renderer just like before using {@link #setCellRenderer(javax.swing.ListCellRenderer)}. CheckBoxList will use your
* cell renderer and automatically put a check box before it.
*
* The selection state is kept in a ListSelectionModel called CheckBoxListSelectionModel, which you can get using {@link
* CheckBoxList#getCheckBoxListSelectionModel()}. If you need to add a check to a check box or to find out if a check
* box is checked, you need to ask the getCheckBoxListSelectionModel() by using addListSelectionListener.
*
* It is possible to add an "(All)" item. All you need to do is to add CheckBoxList.ALL_ENTRY to the list model. Then check
* the (All) item will select all the check boxes and uncheck it will deselect all.
*
* Please note, we changed CheckBoxList implementation in 1.9.2 release. The old CheckBoxList class is renamed to {@link
* CheckBoxListWithSelectable}. If you want to use the old implementation, you can use CheckBoxListWithSelectable
* instead. The main difference between the two implementation is at how the selection state is kept. In new
* implementation, the selection state is kept at a separate ListSelectionModel which you can get using {@link
* CheckBoxList#getCheckBoxListSelectionModel()}. If you need to add a check to a check box or to find out if a check
* box is checked, you need to ask the getCheckBoxListSelectionModel() by using addListSelectionListener. The old
* implementation kept the selection state at Selectable object in the ListModel. The new implementation also has the
* same design as that of {@link CheckBoxTree}.
*/
public class CheckBoxList extends JList {
protected CheckBoxListCellRenderer _listCellRenderer;
public static final String PROPERTY_CHECKBOX_ENABLED = "checkBoxEnabled";
public static final String PROPERTY_CLICK_IN_CHECKBOX_ONLY = "clickInCheckBoxOnly";
private boolean _checkBoxEnabled = true;
private boolean _clickInCheckBoxOnly = true;
private CheckBoxListSelectionModel _checkBoxListSelectionModel;
protected Handler _handler;
/**
* @deprecated replaced by {@link #ALL_ENTRY}
*/
@Deprecated
public static final String ALL = "(All)";
/**
* The default all entry for CheckBoxList.
*
* @since 3.4.1
*/
public static final Object ALL_ENTRY = new AllEntry();
private final static class AllEntry {
public AllEntry() {
}
@Override
public String toString() {
return "(All)";
}
}
/**
* Constructs a CheckBoxList
with an empty model.
*/
public CheckBoxList() {
init();
}
/**
* Constructs a CheckBoxList
that displays the elements in the specified Vector
.
*
* @param listData the Vector
to be loaded into the data model
*/
public CheckBoxList(final Vector> listData) {
super(listData);
init();
}
/**
* Constructs a CheckBoxList
that displays the elements in the specified Object[]
.
*
* @param listData the array of Objects to be loaded into the data model
*/
public CheckBoxList(final Object[] listData) {
super(listData);
init();
}
/**
* Constructs a CheckBoxList
that displays the elements in the specified, non-null
model.
* All CheckBoxList
constructors delegate to this one.
*
*
* @param dataModel the data model for this list
*
* @throws IllegalArgumentException if dataModel
is null
*/
public CheckBoxList(ListModel dataModel) {
super(dataModel);
init();
}
@Override
public void setModel(ListModel model) {
super.setModel(model);
if (getCheckBoxListSelectionModel() != null) {
getCheckBoxListSelectionModel().clearSelection();
}
}
@Override
public void updateUI() {
super.updateUI();
}
/**
* Initialize the CheckBoxList.
*/
protected void init() {
_checkBoxListSelectionModel = createCheckBoxListSelectionModel(getModel());
setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
_listCellRenderer = createCellRenderer();
_handler = createHandler();
_checkBoxListSelectionModel.addListSelectionListener(_handler);
JideSwingUtilities.insertMouseListener(this, _handler, 0);
JideSwingUtilities.insertMouseMotionListener(this, _handler, 0);
addKeyListener(_handler);
addPropertyChangeListener("model", _handler);
ListModel model = getModel();
if (model != null) {
model.addListDataListener(_handler);
}
}
@Override
public int getLastVisibleIndex() {
int visibleIndex = super.getLastVisibleIndex();
if (visibleIndex < 0) {
return getModel().getSize() - 1;
}
return visibleIndex;
}
protected CheckBoxListSelectionModel createCheckBoxListSelectionModel(ListModel model) {
return new CheckBoxListSelectionModel(model);
}
/**
* Creates the cell renderer.
*
* @return the cell renderer.
*/
protected CheckBoxListCellRenderer createCellRenderer() {
return new CheckBoxListCellRenderer();
}
/**
* Creates the mouse listener and key listener used by CheckBoxList.
*
* @return the Handler.
*/
protected Handler createHandler() {
return new Handler(this);
}
@Override
public ListCellRenderer getCellRenderer() {
if (_listCellRenderer != null) {
_listCellRenderer.setActualListRenderer(getActualCellRenderer());
return _listCellRenderer;
}
else {
return super.getCellRenderer();
}
}
public ListCellRenderer getActualCellRenderer() {
return super.getCellRenderer();
}
protected static class Handler implements MouseListener, MouseMotionListener, KeyListener, ListSelectionListener, PropertyChangeListener, ListDataListener {
protected CheckBoxList _list;
int hotspot = new JCheckBox().getPreferredSize().width;
public Handler(CheckBoxList list) {
_list = list;
}
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getOldValue() instanceof ListModel) {
((ListModel) evt.getOldValue()).removeListDataListener(this);
}
if (evt.getNewValue() instanceof ListModel) {
_list.getCheckBoxListSelectionModel().setModel((ListModel) evt.getNewValue());
((ListModel) evt.getNewValue()).addListDataListener(this);
}
}
protected boolean clicksInCheckBox(MouseEvent e) {
int index = _list.locationToIndex(e.getPoint());
Rectangle bounds = _list.getCellBounds(index, index);
if (bounds != null) {
if (_list.getComponentOrientation().isLeftToRight()) {
return e.getX() < bounds.x + hotspot;
}
else {
return e.getX() > bounds.x + bounds.width - hotspot;
}
}
else {
return false;
}
}
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
if (e.isConsumed()) {
return;
}
if (!_list.isCheckBoxEnabled()) {
return;
}
boolean clickInBox = clicksInCheckBox(e);
if (!_list.isClickInCheckBoxOnly() || clickInBox) {
int index = _list.locationToIndex(e.getPoint());
toggleSelection(index);
if (clickInBox) {
Object source = e.getSource();
if(source instanceof JList) {
JList list = ((JList) source);
if (!list.hasFocus() && list.isFocusable() && list.isRequestFocusEnabled()) {
list.requestFocusInWindow();
}
}
e.consume();
}
}
}
@Override
public void mouseDragged(MouseEvent e) {
if (e.isConsumed()) {
return;
}
if (!_list.isCheckBoxEnabled()) {
return;
}
boolean clickInBox = clicksInCheckBox(e);
if (!_list.isClickInCheckBoxOnly() || clickInBox) {
if (clickInBox) {
e.consume();
}
}
}
@Override
public void mouseMoved(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
if (e.isConsumed()) {
return;
}
if (!_list.isCheckBoxEnabled()) {
return;
}
if (clicksInCheckBox(e)) {
e.consume();
}
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void keyPressed(KeyEvent e) {
if (e.isConsumed()) {
return;
}
if (!_list.isCheckBoxEnabled()) {
return;
}
if (e.getModifiers() == 0 && e.getKeyChar() == KeyEvent.VK_SPACE)
toggleSelections();
}
public void keyTyped(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
protected void toggleSelections() {
int[] indices = _list.getSelectedIndices();
CheckBoxListSelectionModel selectionModel = _list.getCheckBoxListSelectionModel();
selectionModel.removeListSelectionListener(this);
selectionModel.setValueIsAdjusting(true);
try {
if (indices.length > 0) {
boolean selected = selectionModel.isSelectedIndex(indices[0]);
for (int index : indices) {
if (!_list.isCheckBoxEnabled(index)) {
continue;
}
if (selected && selectionModel.isSelectedIndex(index)) {
selectionModel.removeSelectionInterval(index, index);
}
else if (!selected && !selectionModel.isSelectedIndex(index)) {
selectionModel.addSelectionInterval(index, index);
}
}
}
}
finally {
selectionModel.setValueIsAdjusting(false);
selectionModel.addListSelectionListener(this);
_list.repaint();
}
}
public void valueChanged(ListSelectionEvent e) {
_list.repaint();
}
protected void toggleSelection(int index) {
if (!_list.isEnabled() || !_list.isCheckBoxEnabled(index)) {
return;
}
CheckBoxListSelectionModel selectionModel = _list.getCheckBoxListSelectionModel();
boolean selected = selectionModel.isSelectedIndex(index);
selectionModel.removeListSelectionListener(this);
try {
if (selected)
selectionModel.removeSelectionInterval(index, index);
else
selectionModel.addSelectionInterval(index, index);
}
finally {
selectionModel.addListSelectionListener(this);
_list.repaint();
}
}
protected void toggleSelection() {
int index = _list.getSelectedIndex();
toggleSelection(index);
}
public void intervalAdded(ListDataEvent e) {
int minIndex = Math.min(e.getIndex0(), e.getIndex1());
int maxIndex = Math.max(e.getIndex0(), e.getIndex1());
/* Sync the SelectionModel with the DataModel.
*/
ListSelectionModel listSelectionModel = _list.getCheckBoxListSelectionModel();
if (listSelectionModel != null) {
listSelectionModel.insertIndexInterval(minIndex, maxIndex - minIndex + 1, true);
}
}
public void intervalRemoved(ListDataEvent e) {
/* Sync the SelectionModel with the DataModel.
*/
ListSelectionModel listSelectionModel = _list.getCheckBoxListSelectionModel();
if (listSelectionModel != null) {
listSelectionModel.removeIndexInterval(e.getIndex0(), e.getIndex1());
}
}
public void contentsChanged(ListDataEvent e) {
}
}
@Override
public int getNextMatch(String prefix, int startIndex, Position.Bias bias) {
return -1;
}
/**
* Checks if check box is enabled. There is no setter for it. The only way is to override this method to return true
* or false.
*
* @param index the row index.
*
* @return true or false. If false, the check box on the particular row index will be disabled.
*/
public boolean isCheckBoxEnabled(int index) {
return true;
}
/**
* Checks if check box is visible. There is no setter for it. The only way is to override this method to return true
* or false.
*
* @param index whether the check box on the row index is visible.
*
* @return true or false. If false, there is not check box on the particular row index. By default, we always return
* true. You override this method to return true of false depending on your need.
*/
@SuppressWarnings({"UnusedDeclaration"})
public boolean isCheckBoxVisible(int index) {
return true;
}
/**
* Gets the value of property checkBoxEnabled. If true, user can click on check boxes on each tree node to select
* and deselect. If false, user can't click but you as developer can programmatically call API to select/deselect
* it.
*
* @return the value of property checkBoxEnabled.
*/
public boolean isCheckBoxEnabled() {
return _checkBoxEnabled;
}
/**
* Sets the value of property checkBoxEnabled.
*
* @param checkBoxEnabled true to allow to check the check box. False to disable it which means user can see whether
* a row is checked or not but they cannot change it.
*/
public void setCheckBoxEnabled(boolean checkBoxEnabled) {
if (checkBoxEnabled != _checkBoxEnabled) {
boolean old = _checkBoxEnabled;
_checkBoxEnabled = checkBoxEnabled;
firePropertyChange(PROPERTY_CHECKBOX_ENABLED, old, _checkBoxEnabled);
repaint();
}
}
/**
* Gets the value of property clickInCheckBoxOnly. If true, user can click on check boxes on each tree node to
* select and deselect. If false, user can't click but you as developer can programmatically call API to
* select/deselect it.
*
* @return the value of property clickInCheckBoxOnly.
*/
public boolean isClickInCheckBoxOnly() {
return _clickInCheckBoxOnly;
}
/**
* Sets the value of property clickInCheckBoxOnly.
*
* @param clickInCheckBoxOnly true to allow to check the check box. False to disable it which means user can see
* whether a row is checked or not but they cannot change it.
*/
public void setClickInCheckBoxOnly(boolean clickInCheckBoxOnly) {
if (clickInCheckBoxOnly != _clickInCheckBoxOnly) {
boolean old = _clickInCheckBoxOnly;
_clickInCheckBoxOnly = clickInCheckBoxOnly;
firePropertyChange(PROPERTY_CLICK_IN_CHECKBOX_ONLY, old, _clickInCheckBoxOnly);
}
}
/**
* Gets the ListSelectionModel that keeps the check boxes' state information for CheckBoxList.
*
* @return the ListSelectionModel that keeps the check boxes' state information for CheckBoxList.
*/
public CheckBoxListSelectionModel getCheckBoxListSelectionModel() {
return _checkBoxListSelectionModel;
}
public void setCheckBoxListSelectionModel(CheckBoxListSelectionModel checkBoxListSelectionModel) {
if (_checkBoxListSelectionModel != checkBoxListSelectionModel) {
if (_checkBoxListSelectionModel != null) {
getModel().removeListDataListener(_checkBoxListSelectionModel);
}
_checkBoxListSelectionModel = checkBoxListSelectionModel;
if (_checkBoxListSelectionModel != null) {
_checkBoxListSelectionModel.setModel(getModel());
}
}
}
/**
* Returns an array of all of the selected indices in increasing order.
*
* @return all of the selected indices, in increasing order
*
* @see #removeSelectionInterval
* @see #addListSelectionListener
*/
public int[] getCheckBoxListSelectedIndices() {
CheckBoxListSelectionModel listSelectionModel = getCheckBoxListSelectionModel();
int iMin = listSelectionModel.getMinSelectionIndex();
int iMax = listSelectionModel.getMaxSelectionIndex();
if ((iMin < 0) || (iMax < 0)) {
return new int[0];
}
int[] temp = new int[1 + (iMax - iMin)];
int n = 0;
for (int i = iMin; i <= iMax; i++) {
if (listSelectionModel.isAllEntryConsidered() && i == listSelectionModel.getAllEntryIndex()) {
continue;
}
if (listSelectionModel.isSelectedIndex(i)) {
temp[n] = i;
n++;
}
}
int[] indices = new int[n];
System.arraycopy(temp, 0, indices, 0, n);
return indices;
}
/**
* Selects a single cell and clear all other selections.
*
* @param index the index of the one cell to select
*
* @see ListSelectionModel#setSelectionInterval
* @see #isSelectedIndex
* @see #addListSelectionListener
*/
public void setCheckBoxListSelectedIndex(int index) {
if (index >= 0 && index < getModel().getSize()) {
getCheckBoxListSelectionModel().setSelectionInterval(index, index);
}
}
/**
* Selects a single cell and keeps all previous selections.
*
* @param index the index of the one cell to select
*
* @see ListSelectionModel#setSelectionInterval
* @see #isSelectedIndex
* @see #addListSelectionListener
*/
public void addCheckBoxListSelectedIndex(int index) {
if (index >= 0 && index < getModel().getSize()) {
getCheckBoxListSelectionModel().addSelectionInterval(index, index);
}
}
/**
* Deselects a single cell.
*
* @param index the index of the one cell to select
*
* @see ListSelectionModel#setSelectionInterval
* @see #isSelectedIndex
* @see #addListSelectionListener
*/
public void removeCheckBoxListSelectedIndex(int index) {
if (index >= 0 && index < getModel().getSize()) {
getCheckBoxListSelectionModel().removeSelectionInterval(index, index);
}
}
/**
* Selects a set of cells.
*
* @param indices an array of the indices of the cells to select
*
* @see ListSelectionModel#addSelectionInterval
* @see #isSelectedIndex
* @see #addListSelectionListener
*/
public void setCheckBoxListSelectedIndices(int[] indices) {
ListSelectionModel listSelectionModel = getCheckBoxListSelectionModel();
try {
listSelectionModel.setValueIsAdjusting(true);
listSelectionModel.clearSelection();
int size = getModel().getSize();
for (int indice : indices) {
if (indice >= 0 && indice < size) {
listSelectionModel.addSelectionInterval(indice, indice);
}
}
}
finally {
listSelectionModel.setValueIsAdjusting(false);
}
}
/**
* Sets the selected elements.
*
* @param elements sets the select elements. All the rows that have the value in the array will be checked.
*/
public void setSelectedObjects(Object[] elements) {
Map
© 2015 - 2025 Weber Informatics LLC | Privacy Policy