org.jdesktop.swingx.renderer.CellContext Maven / Gradle / Ivy
Show all versions of swingx-all Show documentation
/*
* $Id: CellContext.java 3778 2010-09-07 10:10:49Z 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 javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import java.awt.Color;
import java.awt.Font;
import java.io.Serializable;
/**
* Encapsulates a snapshop of cell content and default display context
* for usage by a ComponentProvider
.
*
*
* One part is the super-set of properties that's traditionally passed into the
* core renderers' (Table-, List-, Tree-) getXXCellRendererComponent. Raw
* properties which define the context are
*
*
* - selected
*
- focused
*
- expanded
*
- leaf
*
*
* Similarl to a ComponentAdapter, the properties are a super-set of those for
* a concrete component type. It's up to sub-classes (once the generics will be removed, until
* then the DefaultXXRenderers - PENDING JW: undecided - even after the generics removal, the
* param list in the subclasses are the same) fill any reasonable
* defaults for those not applicable to the specific component context.
*
* With those raw properties given, a CellContext looks up and returns dependent visual
* properties as appropriate for the concrete component. Typically, they are taken
* from the component if supported, or requested from the UIManager.
* Dependent properties are
*
*
* - foreground and background color
*
- border
*
- icon (relevant for trees only)
*
- editable
*
*
* For a backdoor, the cell location (in horizontal and vertical view coordinates)
* and the originating component is accessible as well. Note that they are not necessarily
* valid for the "life" component. It's not recommended to actually use them. If needed,
* that's probably a sign the api is lacking :-)
*
*
*
*
*
* - PENDING: still incomplete? how about Font?
*
- PENDING: protected methods? Probably need to open up - derived
* properties should be accessible in client code.
*
*
* @author Jeanette Winzenburg
*/
public class CellContext implements Serializable {
/**
* the default border for unfocused cells.
*/
protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
/**
* Returns the shared border for unfocused cells.
*
* PENDING: ?? copied from default renderers - why is it done like this?
*
* @return the border for unfocused cells.
*/
private static Border getNoFocusBorder() {
return noFocusBorder;
}
/**
* PENDING JW: maybe make this a WeakReference? Would be a more robust fix for Issue #1040-swingx.
*/
protected transient JComponent component;
/**
* PENDING JW: maybe make this a WeakReference? Would be a more robust fix for Issue #1040-swingx.
*/
protected transient Object value;
protected transient int row;
protected transient int column;
protected transient boolean selected;
protected transient boolean focused;
protected transient boolean expanded;
protected transient boolean leaf;
protected transient boolean dropOn;
// --------------------------- install context
/**
* Sets the state of the cell's context. Convenience method for subclasses.
*
* @param value the content value of the cell
* @param row the cell's row index in view coordinates
* @param column the cell's column index in view coordinates
* @param selected the cell's selected state
* @param focused the cell's focused state
* @param expanded the cell's expanded state
* @param leaf the cell's leaf state
*/
protected void installState(Object value, int row, int column, boolean selected, boolean focused, boolean expanded, boolean leaf) {
this.value = value;
this.row = row;
this.column = column;
this.selected = selected;
this.focused = focused;
this.expanded = expanded;
this.leaf = leaf;
}
/**
* Replaces the value of this cell context with the given parameter and returns
* the replaced value.
*
* @param value the new value of the cell context
* @return the replaced value of the cell context
*/
public Object replaceValue(Object value) {
Object old = getValue();
this.value = value;
return old;
}
// -------------------- accessors of installed state
/**
* Returns the component the cell resides on, may be null. Subclasses are
* expected to override and return the component type they are handling.
*
* @return the component the cell resides on, may be null.
*/
public JComponent getComponent() {
return component;
}
/**
* Returns the value of the cell as set in the install.
*
* @return the content value of the cell.
*/
public Object getValue() {
return value;
}
/**
* Returns the cell's row index in view coordinates as set in the install.
*
* @return the cell's row index.
*/
public int getRow() {
return row;
}
/**
* Returns the cell's column index in view coordinates as set in the
* install.
*
* @return the cell's column index.
*/
public int getColumn() {
return column;
}
/**
* Returns the selected state as set in the install.
*
* @return the cell's selected state.
*/
public boolean isSelected() {
return selected;
}
/**
* Returns the focused state as set in the install.
*
* @return the cell's focused state.
*/
public boolean isFocused() {
return focused;
}
/**
* Returns the expanded state as set in the install.
*
* @return the cell's expanded state.
*/
public boolean isExpanded() {
return expanded;
}
/**
* Returns the leaf state as set in the install.
*
* @return the cell's leaf state.
*/
public boolean isLeaf() {
return leaf;
}
// -------------------- accessors for derived state
/**
* Returns the cell's editability. Subclasses should override to return a
* reasonable cell-related state.
*
*
* Here: false.
*
* @return the cell's editable property.
*/
public boolean isEditable() {
return false;
}
/**
* Returns the icon. Subclasses should override to return a reasonable
* cell-related state.
*
*
* Here: null
.
*
* @return the cell's icon.
*/
public Icon getIcon() {
return null;
}
/**
* Returns a boolean indicating if the cell is a drop location with any of the dropOn
* modes. It's up to subclasses to implement.
*
*
* Here: false.
*
* @return true if the current cell is a drop location with any of the dropOn modes,
* false otherwise
*/
protected boolean isDropOn() {
return dropOn;
}
/**
* Returns the foreground color of the renderered component or null if the
* component is null
*
*
* PENDING: fallback to UI properties if comp == null?
*
* @return the foreground color of the rendered component.
*/
protected Color getForeground() {
if (isDropOn()) {
return getSelectionForeground();
}
return getComponent() != null ? getComponent().getForeground() : null;
}
/**
* Returns the background color of the renderered component or null if the
* component is null
*
*
* PENDING: fallback to UI properties if comp == null?
*
* @return the background color of the rendered component.
*/
protected Color getBackground() {
if (isDropOn()) {
return getSelectionBackground();
}
return getComponent() != null ? getComponent().getBackground() : null;
}
/**
* Returns the default selection background color of the renderered
* component. Typically, the color is LF specific. It's up to subclasses to
* look it up. Here: returns null.
*
*
* PENDING: return UI properties here?
*
* @return the selection background color of the rendered component.
*/
protected Color getSelectionBackground() {
return null;
}
/**
* Returns the default selection foreground color of the renderered
* component. Typically, the color is LF specific. It's up to subclasses to
* look it up. Here: returns null.
*
*
* PENDING: return UI properties here?
*
* @return the selection foreground color of the rendered component.
*/
protected Color getSelectionForeground() {
return null;
}
/**
* Returns the default focus border of the renderered component. Typically,
* the border is LF specific.
*
* @return the focus border of the rendered component.
*/
protected Border getFocusBorder() {
Border border = null;
if (isSelected()) {
border = UIManager.getBorder(getUIKey("focusSelectedCellHighlightBorder"));
}
if (border == null) {
border = UIManager.getBorder(getUIKey("focusCellHighlightBorder"));
}
return border;
}
/**
* Returns the default border of the renderered component depending on cell
* state. Typically, the border is LF specific.
*
*
* Here: returns the focus border if the cell is focused, the context
* defined no focus border otherwise.
*
* @return the default border of the rendered component.
*/
protected Border getBorder() {
if (isFocused()) {
return getFocusBorder();
}
Border border = UIManager.getBorder(getUIKey("cellNoFocusBorder"));
return border != null ? border : getNoFocusBorder();
}
/**
* Returns the default focused foreground color of the renderered component.
* Typically, the color is LF specific.
*
* @return the focused foreground color of the rendered component.
*/
protected Color getFocusForeground() {
return UIManager.getColor(getUIKey("focusCellForeground"));
}
/**
* Returns the default focused background color of the renderered component.
* Typically, the color is LF specific.
*
* @return the focused background color of the rendered component.
*/
protected Color getFocusBackground() {
return UIManager.getColor(getUIKey("focusCellBackground"));
}
protected Color getDropCellForeground() {
return UIManager.getColor(getUIKey("dropCellForeground"));
}
protected Color getDropCellBackground() {
return UIManager.getColor(getUIKey("dropCellBackground"));
}
// ----------------------- convenience
/**
* Convenience method to build a component type specific lookup key for the
* UIManager.
*
* @param key the general part of the key
* @return a composed key build of a component type prefix and the input.
*/
protected String getUIKey(String key) {
return getUIPrefix() + key;
}
/**
* Returns the component type specific prefix of keys for lookup in the
* UIManager. Subclasses must override, here: returns the empty String.
*
* @return the component type specific prefix.
*/
protected String getUIPrefix() {
return "";
}
/**
* Returns the Font of the target component or null if no component installed.
*/
protected Font getFont() {
return getComponent() != null ? getComponent().getFont() : null;
}
public String getCellRendererName() {
return getUIPrefix() + "cellRenderer";
}
}