package com.onaro.sanscreen.client.view.tabular.columns; import java.awt.Component; import java.awt.Graphics; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellRenderer; import org.apache.commons.lang3.StringUtils; import com.onaro.util.enumeration.EnumPresentation; import com.onaro.util.enumeration.EnumPresentation.Attributes; import com.onaro.util.jfc.tables.filter.EnumFilter; import com.onaro.util.jfc.tables.filter.Filter; import com.onaro.util.jfc.tables.renderers.SimpleTableCellRenderer; /** * Class that presents icons to indicate the value of a boolean property of an Adaptable. * Often an icon is only displayed only for {@code true} values, with {@code false} * values displayed as a blank cell. However, the class supports display of an icon only * for {@code false} values, or one icon for {@code true} values and another icon for * {@code false} values. The column supports filtering, using an EnumFilter listing the * icon(s) along with All (cancel filtering) and Empty (no icon). */ public class BooleanIconValuePresenter extends AbstractColumnValuePresenter { public BooleanIconValuePresenter(Icon trueIcon, Icon falseIcon) { super(EnumPresentation.Attributes.class); if (trueIcon == null && falseIcon == null) { throw new IllegalArgumentException ("No icon defined"); //$NON-NLS-1$ } this.trueIcon = trueIcon; this.truePresentation = trueIcon == null? null : new Presentation (trueIcon, true); this.falseIcon = falseIcon; this.falsePresentation = falseIcon == null? null : new Presentation (falseIcon, false); this.renderer = new Renderer(); } @Override public Filter createCustomFilter() { EnumPresentation.Attributes[] attrs; if (falsePresentation == null) { attrs = new EnumPresentation.Attributes[1]; attrs[0]= truePresentation; } else if (truePresentation == null) { attrs = new EnumPresentation.Attributes[1]; attrs[0]= falsePresentation; } else { attrs = new EnumPresentation.Attributes[2]; attrs[0]= truePresentation; attrs[1]= falsePresentation; } return new EnumFilter (attrs); } @Override public TableCellRenderer createCustomRenderer() { return renderer; } @Override public Attributes getPresentation(Boolean value, String identifier) { return value != null && value.booleanValue()? truePresentation : falsePresentation; } /** * Get the cell value used for {@code true} property values. * This wraps the icon and is used for filtering. * @return {@link EnumPresentation.Attributes} * or {@code null} if there is no icon for {@code true} values */ public EnumPresentation.Attributes getTruePresentation() { return truePresentation; } /** * Get the cell value used for {@code false} property values. * This wraps the icon and is used for filtering. * @return {@link EnumPresentation.Attributes} * or {@code null} if there is no icon for {@code false} values */ public EnumPresentation.Attributes getFalsePresentation() { return falsePresentation; } /** * Get icon used to represent {@code true} values * @return {@link Icon} * or {@code null} if there is no icon for {@code true} values */ public Icon getTrueIcon() { return trueIcon; } /** * Get icon used to represent {@code false} values * @return {@link Icon} * or {@code null} if there is no icon for {@code false} values */ public Icon getFalseIcon() { return falseIcon; } /** * Wrapped icon implementation that will return true/false as its toString(), for RFT testing. * Extends EnumPresentation.Attributes so column can use EnumFilter. */ private static class Presentation extends EnumPresentation.Attributes implements Icon { public Presentation (Icon icon, boolean value) { // Set ordinal EnumPresentation value to 1 or 2 for true or false icon. super (value? "1" : "2", StringUtils.EMPTY); //$NON-NLS-1$ //$NON-NLS-2$ this.wrappedIcon = icon; this.isTrue = value; smallIcon = this.new Image(); // Convert Icon to ImageIcon. } @Override public int getIconHeight() { return wrappedIcon.getIconHeight(); } @Override public int getIconWidth() { return wrappedIcon.getIconWidth(); } @Override public void paintIcon (Component c, Graphics g, int x, int y) { wrappedIcon.paintIcon (c, g, x, y); } @Override public int compareTo (EnumPresentation.Attributes object) { if (this == object) { return 0; } if (object instanceof Presentation) { // Sort true Presentations before false Presentations. return this.isTrue? -1 : 1; } return super.compareTo (object); } @Override public boolean equals (Object object) { if (this == object) { return true; } if (object instanceof Presentation) { return this.isTrue == ( (Presentation)object).isTrue; } return super.equals (object); } @Override public int hashCode() { return Boolean.valueOf (isTrue).hashCode(); } /** * This method MUST be implemented for the RFT. */ @Override public String toString() { return String.valueOf (isTrue); } /** * EnumPresentation.Attributes requires an ImageIcon instead of an Icon. * So this class presents the wrapped Icon as an ImageIcon. */ private class Image extends ImageIcon { @Override public int getIconHeight() { return wrappedIcon.getIconHeight(); } @Override public int getIconWidth() { return wrappedIcon.getIconWidth(); } @Override public void paintIcon (Component c, Graphics g, int x, int y) { wrappedIcon.paintIcon (c, g, x, y); } private static final long serialVersionUID = 1L; } private final Icon wrappedIcon; private final boolean isTrue; } /** * Renderer to display the icon. *

* Can't use {@link SimpleTableCellRenderer} because it displays {@link Presentation#toString()} * along with the icon. The string ("true" or "false") is defined only for testing; * it's not intended for display. SimpleTableCellRenderer also has features not used * for icon display. */ private static class Renderer extends DefaultTableCellRenderer { /** * Create a renderer that displays an icon in the top center of the cell. */ public Renderer() { setHorizontalAlignment (CENTER); setVerticalAlignment (TOP); setHorizontalAlignment(CENTER); // Don't display text, just display icon. setText (null); } @Override protected void setValue (Object value) { if (value instanceof Presentation) { setIcon (((Presentation)value).smallIcon); } else { setIcon (null); } } private static final long serialVersionUID = 1L; } private final Icon trueIcon; private final Icon falseIcon; private final Presentation truePresentation; private final Presentation falsePresentation; private final Renderer renderer; }