org.jdesktop.swingx.renderer.ComponentProvider Maven / Gradle / Ivy
Show all versions of swingx-all Show documentation
/*
* $Id: ComponentProvider.java 3927 2011-02-22 16:34:11Z kleopatra $
*
* Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle,
* Santa Clara, California 95054, U.S.A. All rights reserved.
*
* 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 2.1 of the License, or (at your option) any later version.
*
* This library 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package org.jdesktop.swingx.renderer;
import java.io.Serializable;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import org.jdesktop.swingx.plaf.UIDependent;
/**
* Abstract base class of a provider for a cell rendering component. Configures
* the component's content and default visuals depending on the renderee's state
* as captured in a CellContext
. It's basically re-usable across
* all types of renderees (JTable, JList, JTree).
*
*
*
Content
*
* A provider guarantees to configure the "content" properties completely
* for any given object. The most frequent mappings are to text and/or icon
* properties of the rendering components. The former is controlled by a
* StringValue (see below), the latter by an IconValue. Subclasses which
* hand out component of type IconAware guarantee to reset its icon property
* always.
*
* To ease content configuration, it supports a pluggable
* StringValue
which purpose is to create and return a string
* representation of a given object. Implemenations of a ComponentProvider can
* use it to configure their rendering component as appropriate.
*
* F.i. to show a Contributor cell object as "Busywoman, Herta" implement a
* custom StringValue and use it in a text rendering provider. (Note that SwingX
* default implementations of Table/List/TreeCellRenderer have convenience
* constructors to take the converter and create a default LabelProvider which
* uses it).
*
*
* StringValue stringValue = new StringValue() {
*
* public String getString(Object value) {
* if (!(value instanceof Contributor))
* return TO_STRING.getString(value);
* Contributor contributor = (Contributor) value;
* return contributor.lastName + ", " + contributor.firstName;
* }
*
* };
* table.setDefaultRenderer(Contributor.class, new DefaultTableRenderer(
* stringValue));
* list.setCellRenderer(new DefaultListRenderer(stringValue));
* tree.setCellRenderer(new DefaultTreeRenderer(stringValue));
*
*
*
* To ease handling of formatted localizable content, there's a
* FormatStringValue
which is pluggable with a
* Format
.
*
* F.i. to show a Date's time in the default Locale's SHORT
* version and right align the cell
*
*
* StringValue stringValue = new FormatStringValue(
* DateFormat.getTimeInstance(DateFormat.SHORT));
* table.getColumnExt("timeID").setCellRenderer(
* new DefaultTableRenderer(stringValue, JLabel.RIGHT);
*
*
*
*
*
*
*
Default Visuals
*
* Guarantees to completely configure the visual properties listed below. As a
* consequence, client code (f.i. in Highlighter
s) can safely
* change them without long-lasting visual artefacts.
*
*
* - foreground and background, depending on selected and focused state
*
- border
*
- font
*
- Painter (if applicable)
*
- enabled
*
- componentOrientation
*
- tooltipText
*
- minimum-, maximum-, preferredSize
*
- horizontal alignment (if applicable)
*
*
* As this internally delegates default visual configuration to a
* DefaultVisuals
(which handles the first eight items)
* subclasses have to guarantee the alignment only.
*
*
*
* @see StringValue
* @see FormatStringValue
* @see IconValue
* @see BooleanValue
* @see CellContext
* @see DefaultTableRenderer
* @see DefaultListRenderer
* @see DefaultTreeRenderer
* @see DefaultVisuals
*/
public abstract class ComponentProvider
implements Serializable, UIDependent {
/** component to render with. */
protected T rendererComponent;
/** configurator of default visuals. */
protected DefaultVisuals defaultVisuals;
/** horizontal (text) alignment of component.
* PENDING: useful only for labels, buttons? */
protected int alignment;
/** the converter to use for string representation.
* PENDING: IconValue? */
protected StringValue formatter;
/**
* Instantiates a component provider with LEADING
* horizontal alignment and default to-String converter.
*
*/
public ComponentProvider() {
this(null, JLabel.LEADING);
}
/**
* Instantiates a component provider with LEADING
* horizontal alignment and the given converter.
*
* @param converter the converter to use for mapping the cell value to a
* String representation.
*/
public ComponentProvider(StringValue converter) {
this(converter, JLabel.LEADING);
}
/**
* Instantiates a LabelProvider with given to-String converter and given
* horizontal alignment. If the converter is null, the default TO_STRING is
* used.
*
* @param converter the converter to use for mapping the cell value to a
* String representation.
* @param alignment the horizontal alignment.
*/
public ComponentProvider(StringValue converter, int alignment) {
setHorizontalAlignment(alignment);
setStringValue(converter);
rendererComponent = createRendererComponent();
defaultVisuals = createDefaultVisuals();
}
/**
* Configures and returns an appropriate component to render a cell
* in the given context. If the context is null, returns the
* component in its current state.
*
* @param context the cell context to configure from
* @return a component to render a cell in the given context.
*/
public T getRendererComponent(CellContext context) {
if (context != null) {
configureVisuals(context);
configureContent(context);
}
return rendererComponent;
}
/**
* Sets the horizontal alignment property to configure the component with.
* Allowed values are those accepted by corresponding JLabel setter. The
* default value is JLabel.LEADING. This controller guarantees to apply the
* alignment on each request for a configured rendering component, if
* possible. Note that not all components have a horizontal alignment
* property.
*
* @param alignment the horizontal alignment to use when configuring the
* rendering component.
*/
public void setHorizontalAlignment(int alignment) {
this.alignment = alignment;
}
/**
* Returns the horizontal alignment.
*
* @return the horizontal alignment of the rendering component.
*
* @see #setHorizontalAlignment(int)
*
*/
public int getHorizontalAlignment() {
return alignment;
}
/**
* Sets the StringValue to use. If the given StringValue is null,
* defaults to StringValue.TO_STRING
.
*
* @param formatter the format to use.
*/
public void setStringValue(StringValue formatter) {
if (formatter == null) {
formatter = StringValues.TO_STRING;
}
this.formatter = formatter;
}
/**
* Returns the StringValue to use for obtaining
* the String representation.
*
* @return the StringValue used by this provider, guaranteed to
* be not null.
*/
public StringValue getStringValue() {
return formatter;
}
/**
* Returns a string representation of the content.
*
*
* This method guarantees to return the same string representation as would
* appear in the renderer, given that the corresponding cellContext has the
* same value as the parameter passed-in here. That is (assuming that the
* rendering component has a getText())
*
*
* if (equals(value, context.getValue()) {
* assertEquals(provider.getString(value),
* provider.getRenderingComponent(context).getText());
* }
*
*
* This implementation simply delegates to its StringValue. Subclasses might
* need to override to comply.
*
*
* This is a second attempt - the driving force is the need for a consistent
* string representation across all (new and old) themes: rendering,
* (pattern) filtering/highlighting, searching, auto-complete ...
*
*
* @param value the object to represent as string.
* @return a appropriate string representation of the cell's content.
*/
public String getString(Object value) {
return formatter.getString(value);
}
/**
* Returns a String representation of the content.
*
* This method messages the
* StringValue
to get the String rep. Meant as
* a convenience for subclasses.
*
* @param context the cell context, must not be null.
* @return a appropriate string representation of the cell's content.
*/
protected String getValueAsString(CellContext context) {
Object value = context.getValue();
return formatter.getString(value);
}
/**
* Returns a Icon representation of the content.
*
* This method messages the
* IconValue
to get the Icon rep. Meant as
* a convenience for subclasses.
*
* @param context the cell context, must not be null.
* @return a appropriate icon representation of the cell's content,
* or null if non if available.
*/
protected Icon getValueAsIcon(CellContext context) {
Object value = context.getValue();
if (formatter instanceof IconValue) {
return ((IconValue) formatter).getIcon(value);
}
return null;
}
/**
* Configures the rendering component's default visuals frome
* the given cell context. Here: delegates to the renderer
* controller.
*
* @param context the cell context to configure from, must not be null.
* @see DefaultVisuals
*/
protected void configureVisuals(CellContext context) {
defaultVisuals.configureVisuals(rendererComponent, context);
}
/**
* Configures the renderering component's content and state from the
* given cell context.
*
* @param context the cell context to configure from, must not be null.
*
* @see #configureState(CellContext)
* @see #format(CellContext)
*/
protected void configureContent(CellContext context) {
configureState(context);
format(context);
}
/**
* Formats the renderering component's content from the
* given cell context.
*
* @param context the cell context to configure from, must not be null.
*/
protected abstract void format(CellContext context);
/**
* Configures the rendering component's state from the
* given cell context.
* @param context the cell context to configure from, must not be null.
*/
protected abstract void configureState(CellContext context);
/**
* Factory method to create and return the component to use for rendering.
*
* @return the component to use for rendering.
*/
protected abstract T createRendererComponent();
/**
* Factory method to create and return the DefaultVisuals used by this
* to configure the default visuals. Here: creates the default controller
* parameterized to the same type as this.
*
* @return the controller used to configure the default visuals of
* the rendering component.
*/
protected DefaultVisuals createDefaultVisuals() {
return new DefaultVisuals();
}
/**
* Intermediate exposure during refactoring...
*
* @return the default visual configurator used by this.
*/
protected DefaultVisuals getDefaultVisuals() {
return defaultVisuals;
}
/**
* {@inheritDoc}
*/
@Override
public void updateUI() {
SwingUtilities.updateComponentTreeUI(rendererComponent);
}
}