/*
* @(#)CheckBoxtListCellRenderer.java 5/11/2005
*
* Copyright 2002 - 2005 JIDE Software Inc. All rights reserved.
*/
package com.jidesoft.swing;
import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.io.Serializable;
import java.util.Locale;
/**
* Renders an item in a list using JCheckBox.
*/
public class CheckBoxListCellRenderer extends JPanel implements ListCellRenderer, Serializable {
private static final long serialVersionUID = 2003073492549917883L;
/**
* The checkbox that is used to paint the check box in cell renderer
*/
protected AbstractButton _checkBox = new NullCheckBox();
protected JLabel _label = new NullLabel();
/**
* The label which appears after the check box.
*/
protected ListCellRenderer _actualListRenderer;
public CheckBoxListCellRenderer(ListCellRenderer renderer) {
_checkBox.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 2));
_checkBox.setOpaque(false);
setOpaque(true);
setLayout(new BorderLayout(0, 0));
add(_checkBox, BorderLayout.BEFORE_LINE_BEGINS);
_actualListRenderer = renderer;
}
/**
* Constructs a default renderer object for an item in a list.
*/
public CheckBoxListCellRenderer() {
this(null);
}
public ListCellRenderer getActualListRenderer() {
return _actualListRenderer;
}
public void setActualListRenderer(ListCellRenderer actualListRenderer) {
_actualListRenderer = actualListRenderer;
}
@Override
public String getToolTipText(MouseEvent event) {
if (_actualListRenderer instanceof JComponent) {
Point p = event.getPoint();
p.translate(-_checkBox.getWidth(), 0);
MouseEvent newEvent = new MouseEvent(((JComponent) _actualListRenderer), event.getID(),
event.getWhen(),
event.getModifiers(),
p.x, p.y, event.getClickCount(),
event.isPopupTrigger());
String tip = ((JComponent) _actualListRenderer).getToolTipText(
newEvent);
if (tip != null) {
return tip;
}
}
return super.getToolTipText(event);
}
public Component getListCellRendererComponent(JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
applyComponentOrientation(list.getComponentOrientation());
setLocale(list.getLocale());
Object actualValue;
if (list instanceof CheckBoxList) {
CheckBoxListSelectionModel selectionModel = ((CheckBoxList) list).getCheckBoxListSelectionModel();
if (selectionModel != null) {
boolean enabled = list.isEnabled()
&& ((CheckBoxList) list).isCheckBoxEnabled()
&& ((CheckBoxList) list).isCheckBoxEnabled(index);
if (!enabled && !isSelected) {
if (getBackground() != null) {
setForeground(getBackground().darker());
}
}
_checkBox.setEnabled(enabled);
_checkBox.setSelected(selectionModel.isSelectedIndex(index));
}
actualValue = value;
}
else if (list instanceof CheckBoxListWithSelectable) {
if (value instanceof Selectable) {
_checkBox.setSelected(((Selectable) value).isSelected());
boolean enabled = list.isEnabled() && ((Selectable) value).isEnabled() && ((CheckBoxListWithSelectable) list).isCheckBoxEnabled();
if (!enabled && !isSelected) {
setForeground(getBackground().darker());
}
_checkBox.setEnabled(enabled);
}
else {
boolean enabled = list.isEnabled();
if (!enabled && !isSelected) {
setForeground(getBackground().darker());
}
_checkBox.setEnabled(enabled);
}
if (value instanceof DefaultSelectable) {
actualValue = ((DefaultSelectable) value).getObject();
}
else {
actualValue = value;
}
}
else {
throw new IllegalArgumentException("CheckBoxListCellRenderer should only be used for CheckBoxList.");
}
if (_actualListRenderer != null) {
JComponent listCellRendererComponent = (JComponent) _actualListRenderer.getListCellRendererComponent(list, actualValue, index, isSelected, cellHasFocus);
// make sure the (All) is converted to the localized string.
if (listCellRendererComponent instanceof JLabel) {
String v = convertElementToString(getLocale(), ((JLabel) listCellRendererComponent).getText());
((JLabel) listCellRendererComponent).setText(v);
}
if (list instanceof CheckBoxListWithSelectable) {
if (!((CheckBoxListWithSelectable) list).isCheckBoxVisible(index)) {
return listCellRendererComponent;
}
}
if (list instanceof CheckBoxList) {
if (!((CheckBoxList) list).isCheckBoxVisible(index)) {
return listCellRendererComponent;
}
}
Border border = listCellRendererComponent.getBorder();
setBorder(border);
listCellRendererComponent.setBorder(BorderFactory.createEmptyBorder());
if (getComponentCount() == 2) {
remove(1);
}
add(listCellRendererComponent);
// copy the background and foreground for the renderer component
setBackground(listCellRendererComponent.getBackground());
listCellRendererComponent.setBackground(null);
setForeground(listCellRendererComponent.getForeground());
listCellRendererComponent.setForeground(null);
listCellRendererComponent.setEnabled(_checkBox.isEnabled());
}
else {
if (isSelected) {
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
}
else {
setBackground(list.getBackground());
setForeground(list.getForeground());
}
if (getComponentCount() == 2) {
remove(1);
}
add(_label);
customizeDefaultCellRenderer(actualValue);
setFont(list.getFont());
}
return this;
}
private String convertElementToString(Locale locale, Object value) {
if (CheckBoxList.ALL_ENTRY.equals(value)) {
return Resource.getResourceBundle(locale).getString("CheckBoxList.all");
}
return (value == null) ? "" : value.toString();
}
/**
* Customizes the cell renderer. By default, it will use toString to covert the object and use it as the text for
* the checkbox. You can subclass it to set an icon, change alignment etc. Since "this" is a JCheckBox, you can call
* all methods available on JCheckBox in the overridden method.
*
* @param value the value on the cell renderer.
*/
protected void customizeDefaultCellRenderer(Object value) {
if (value instanceof Icon) {
_label.setIcon((Icon) value);
_label.setText("");
}
else {
_label.setIcon(null);
_label.setText(convertElementToString(getLocale(), value));
}
}
/**
* A subclass of CheckBoxListCellRenderer that implements UIResource. CheckBoxListCellRenderer doesn't implement
* UIResource directly so that applications can safely override the cellRenderer property with
* CheckBoxListCellRenderer subclasses.
* <p/>
* <strong>Warning:</strong> Serialized objects of this class will not be compatible with future Swing releases. The
* current serialization support is appropriate for short term storage or RMI between applications running the same
* version of Swing. As of 1.4, support for long term storage of all JavaBeans<sup><font size="-2">TM</font></sup>
* has been added to the <code>java.beans</code> package. Please see {@link java.beans.XMLEncoder}.
*/
public static class UIResource extends CheckBoxListCellRenderer
implements javax.swing.plaf.UIResource {
}
}