001/*
002 * $Id: CheckBoxProvider.java 3152 2008-12-23 18:12:39Z kschaefe $
003 *
004 * Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle,
005 * Santa Clara, California 95054, U.S.A. All rights reserved.
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 * 
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015 * Lesser General Public License for more details.
016 * 
017 * You should have received a copy of the GNU Lesser General Public
018 * License along with this library; if not, write to the Free Software
019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
020 */
021package org.jdesktop.swingx.renderer;
022
023import javax.swing.AbstractButton;
024import javax.swing.JLabel;
025
026/**
027 * A component provider which uses a JCheckBox.
028 * <p>
029 * 
030 * This implementation respects a BooleanValue and a StringValue to configure
031 * the button's selected and text property. By default, the selected is mapped
032 * to a Boolean-type value and the text is empty.
033 * <p>
034 * 
035 * To allow mapping to different types, client code can supply a custom
036 * StringValue which also implements BooleanValue. F.i. to render a cell value
037 * of type TableColumnExt with the column's visibility mapped to the selected
038 * and the column's title to the text:
039 * 
040 * <pre><code>
041 *            
042 *     BooleanValue bv = new BooleanValue(){
043 *        public boolean getBoolean(Object value) {
044 *           if (value instanceof TableColumnExt) 
045 *               return ((TableColumnExt) value).isVisible();
046 *           return false;
047 *        }
048 *     };
049 *     StringValue sv = new StringValue() {
050 *         public String getString(Object value) {
051 *           if (value instanceof TableColumnExt) 
052 *               return ((TableColumnExt) value).getTitle();
053 *           return &quot;&quot;;
054 *         }
055 *     };
056 *     list.setCellRenderer(new DefaultListRenderer(
057 *           new CheckBoxProvider(new MappedValue(sv, null, bv), JLabel.LEADING))); 
058 * </code></pre>
059 * 
060 * 
061 * @see BooleanValue
062 * @see StringValue
063 * @see MappedValue
064 * 
065 * @author Jeanette Winzenburg
066 */
067public class CheckBoxProvider extends ComponentProvider<AbstractButton> {
068
069    private boolean borderPainted;
070
071    /**
072     * Instantiates a CheckBoxProvider with default properties. <p> 
073     *
074     */
075    public CheckBoxProvider() {
076        this(null);
077    }
078
079    /**
080     * Instantiates a CheckBoxProvider with the given StringValue and default
081     * alignment.
082     * 
083     * @param stringValue the StringValue to use for formatting.
084     */
085    public CheckBoxProvider(StringValue stringValue) {
086        this(stringValue, JLabel.CENTER);
087    }
088
089    /**
090     * Instantiates a CheckBoxProvider with the given StringValue and
091     * alignment. 
092     * 
093     * @param stringValue the StringValue to use for formatting.
094     * @param alignment the horizontalAlignment.
095     */
096    public CheckBoxProvider(StringValue stringValue, int alignment) {
097        super(stringValue == null ? StringValues.EMPTY : stringValue, alignment);
098        setBorderPainted(true);
099    }
100
101
102    /**
103     * Returns the border painted flag.
104     * @return the borderpainted flag to use on the checkbox.
105     * @see #setBorderPainted(boolean)
106     */
107    public boolean isBorderPainted() {
108        return borderPainted;
109    }
110
111    /**
112     * Sets the border painted flag. The underlying checkbox
113     * is configured with this value on every request.<p>
114     * 
115     * The default value is true.
116     * 
117     * @param borderPainted the borderPainted property to configure
118     *   the underlying checkbox with.
119     *   
120     *  @see #isBorderPainted() 
121     */
122    public void setBorderPainted(boolean borderPainted) {
123        this.borderPainted = borderPainted;
124    }
125
126    /**
127     * {@inheritDoc} <p>
128     * Overridden to set the button's selected state and text.<p>
129     * 
130     *  PENDING: set icon?
131     *  
132     *  @see #getValueAsBoolean(CellContext)
133     *  @see #getValueAsString(CellContext)
134     */
135    @Override
136    protected void format(CellContext context) {
137        rendererComponent.setSelected(getValueAsBoolean(context));
138        rendererComponent.setText(getValueAsString(context));
139    }
140
141    /**
142     * Returns a boolean representation of the content.<p>
143     * 
144     * This method messages the 
145     * <code>BooleanValue</code> to get the boolean rep. If none available,
146     * checks for Boolean type directly and returns its value. Returns
147     * false otherwise. <p>
148     * 
149     * PENDING: fallback to check for boolean is convenient .. could cleanup
150     *   to use a default BooleanValue instead.
151     * 
152     * @param context the cell context, must not be null.
153     * @return the boolean representation of the cell's content,
154     *   or false if none if available.
155     */
156    protected boolean getValueAsBoolean(CellContext context) {
157        if (formatter instanceof BooleanValue) {
158            return ((BooleanValue) formatter).getBoolean(context.getValue());
159        }
160        return Boolean.TRUE.equals(context.getValue());
161    }
162
163    /**
164     * {@inheritDoc}<p>
165     * 
166     * Here: set's the buttons horizontal alignment and borderpainted properties
167     * to this provider's properties.
168     */
169    @Override
170    protected void configureState(CellContext context) {
171        rendererComponent.setBorderPainted(isBorderPainted());
172        rendererComponent.setHorizontalAlignment(getHorizontalAlignment());
173    }
174
175    /**
176     * {@inheritDoc}<p>
177     * Here: returns a JCheckBox as rendering component.<p>
178     * 
179     */
180    @Override
181    protected AbstractButton createRendererComponent() {
182        return new JRendererCheckBox();
183    }
184
185}