HtmlRenderer
. If the underlying
+ * FileSystem.Status
is an instance of HmlStatus,
+ * this method will return non-null if status information is added.
+ *
+ * @return a string containing compliant HTML markup or null
+ * @see org.openide.awt.HtmlRenderer
+ * @see org.openide.nodes.Node.getHtmlDisplayName */
+ public String getHtmlDisplayName() {
+ try {
+ FileSystem.Status stat =
+ obj.getPrimaryFile().getFileSystem().getStatus();
+ if (stat instanceof HtmlStatus) {
+ HtmlStatus hstat = (HtmlStatus) stat;
+
+ String result = hstat.annotateNameHtml (
+ super.getDisplayName(), new LazyFilesSet());
+
+ //Make sure the super string was really modified
+ if (!super.getDisplayName().equals(result)) {
+ return result;
+ }
+ }
+ } catch (FileStateInvalidException e) {
+ //do nothing and fall through
+ }
+ return super.getHtmlDisplayName();
+ }
/** Get the displayed icon for this node.
* A filesystem may {@link org.openide.filesystems.FileSystem#getStatus specially alter} this.
Index: openide/src/org/openide/explorer/propertysheet/ComboInplaceEditor.java
===================================================================
RCS file: /cvs/openide/src/org/openide/explorer/propertysheet/ComboInplaceEditor.java,v
retrieving revision 1.21
diff -c -r1.21 ComboInplaceEditor.java
*** openide/src/org/openide/explorer/propertysheet/ComboInplaceEditor.java 1 Mar 2004 05:14:00 -0000 1.21
--- openide/src/org/openide/explorer/propertysheet/ComboInplaceEditor.java 9 Mar 2004 23:28:05 -0000
***************
*** 21,26 ****
--- 21,27 ----
import javax.swing.plaf.ComboBoxUI;
import javax.swing.plaf.metal.MetalLookAndFeel;
import javax.swing.text.JTextComponent;
+ import org.openide.awt.HtmlRenderer;
import org.openide.explorer.propertysheet.editors.EnhancedPropertyEditor;
/** A combo box inplace editor. Does a couple of necessary things:
***************
*** 60,66 ****
* less borders & such */
public ComboInplaceEditor(boolean tableUI) {
if (tableUI) {
! putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
}
if (Boolean.getBoolean("netbeans.ps.combohack")) { //NOI18N
setLightWeightPopupEnabled(false);
--- 61,67 ----
* less borders & such */
public ComboInplaceEditor(boolean tableUI) {
if (tableUI) {
! putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE); //NOI18N
}
if (Boolean.getBoolean("netbeans.ps.combohack")) { //NOI18N
setLightWeightPopupEnabled(false);
***************
*** 73,78 ****
--- 74,95 ----
updateUI();
}
}
+
+ /** Uses the shared instance of the fast HTML renderer */
+ public ListCellRenderer getRenderer() {
+ ListCellRenderer result = HtmlRenderer.sharedInstance();
+ ((JComponent) result).setBorder (BorderFactory.createEmptyBorder (
+ 0,
+ PropUtils.getTextMargin(),
+ 0,
+ 0));
+ //Popups should paint as the focused component even though the combo
+ //is what has focus
+ ((HtmlRenderer) result).setPaintAsFocused(true);
+ ((HtmlRenderer) result).setIcon(null);
+ ((HtmlRenderer) result).setOpaque(false);
+ return result;
+ }
/** Overridden to add a listener to the editor if necessary, since the
* UI won't do that for us without a focus listener */
Index: openide/src/org/openide/explorer/propertysheet/PropUtils.java
===================================================================
RCS file: /cvs/openide/src/org/openide/explorer/propertysheet/PropUtils.java,v
retrieving revision 1.33
diff -c -r1.33 PropUtils.java
*** openide/src/org/openide/explorer/propertysheet/PropUtils.java 29 Feb 2004 03:56:21 -0000 1.33
--- openide/src/org/openide/explorer/propertysheet/PropUtils.java 9 Mar 2004 23:28:09 -0000
***************
*** 35,40 ****
--- 35,41 ----
import org.netbeans.modules.openide.explorer.PsSettings;
import org.openide.nodes.Node.*;
import org.openide.*;
+ import org.openide.awt.HtmlRenderer;
import org.openide.util.*;
import org.openide.nodes.*;
***************
*** 326,349 ****
/** Get a scratch graphics object which can be used to calculate string
* widths offscreen */
static Graphics getScratchGraphics(Component c) {
! //OS-X 1.4.1 calling getGraphics() can cause cyclic repaints
! //if called while painting. Safer to use an offscreen, cached
! //resource, probably everywhere.
! Graphics result = null; //c.getGraphics();
! if (result == null) {
! //xxx this grabs the AWT tree lock
! /*
! result =
! GraphicsEnvironment.getLocalGraphicsEnvironment
! ().getDefaultScreenDevice().getDefaultConfiguration
! ().createCompatibleImage(1,1).getGraphics();
! */
! if (scratch == null) {
! scratch = new BufferedImage(1,1,BufferedImage.TYPE_INT_ARGB);
! }
! result = scratch.getGraphics();
! }
! return result;
}
--- 327,333 ----
/** Get a scratch graphics object which can be used to calculate string
* widths offscreen */
static Graphics getScratchGraphics(Component c) {
! return HtmlRenderer.sharedInstance().getGraphics();
}
Index: openide/src/org/openide/explorer/propertysheet/RendererFactory.java
===================================================================
RCS file: /cvs/openide/src/org/openide/explorer/propertysheet/RendererFactory.java,v
retrieving revision 1.10
diff -c -r1.10 RendererFactory.java
*** openide/src/org/openide/explorer/propertysheet/RendererFactory.java 25 Feb 2004 00:45:00 -0000 1.10
--- openide/src/org/openide/explorer/propertysheet/RendererFactory.java 9 Mar 2004 23:28:12 -0000
***************
*** 21,30 ****
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
- import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
- import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
--- 21,28 ----
***************
*** 47,54 ****
import javax.swing.border.BevelBorder;
import javax.swing.border.Border;
import javax.swing.event.ChangeListener;
- import javax.swing.table.DefaultTableCellRenderer;
import org.openide.ErrorManager;
import org.openide.nodes.Node.Property;
import org.openide.util.Utilities;
--- 45,52 ----
import javax.swing.border.BevelBorder;
import javax.swing.border.Border;
import javax.swing.event.ChangeListener;
import org.openide.ErrorManager;
+ import org.openide.awt.HtmlRenderer;
import org.openide.nodes.Node.Property;
import org.openide.util.Utilities;
***************
*** 236,246 ****
return lbl;
}
! public JLabel getStringRenderer() {
StringRenderer result = stringRenderer();
result.clear();
result.setEnabled(true);
! return (JLabel) result;
}
private JComponent prepareRadioButtons(PropertyEditor editor, PropertyEnv env) {
--- 234,244 ----
return lbl;
}
! public HtmlRenderer getStringRenderer() {
StringRenderer result = stringRenderer();
result.clear();
result.setEnabled(true);
! return result;
}
private JComponent prepareRadioButtons(PropertyEditor editor, PropertyEnv env) {
***************
*** 426,439 ****
/** Overridden only fire those properties needed */
protected void firePropertyChange(String name, Object old, Object nue) {
! //gtk L&F needs these, although bg and fg don't work on it in 1.4.2
! /*
! if ("foreground".equals(name) ||
! "background".equals(name) || "font".equals(name) ||
! "editable".equals(name) || "enabled".equals(name)) { //NOI18N
! super.firePropertyChange(name, old, nue);
! }
! */
super.firePropertyChange(name,old,nue);
}
--- 424,430 ----
/** Overridden only fire those properties needed */
protected void firePropertyChange(String name, Object old, Object nue) {
! //firing all changes for now - breaks text painting on OS-X
super.firePropertyChange(name,old,nue);
}
***************
*** 495,501 ****
/** A renderer for string properties, which can also delegate to the
* property editor's paint()
method if possible. */
! private static final class StringRenderer extends DefaultTableCellRenderer implements InplaceEditor {
private PropertyEditor editor=null;
private PropertyEnv env=null;
private boolean tableUI=false;
--- 486,492 ----
/** A renderer for string properties, which can also delegate to the
* property editor's paint()
method if possible. */
! private static final class StringRenderer extends HtmlRenderer implements InplaceEditor {
private PropertyEditor editor=null;
private PropertyEnv env=null;
private boolean tableUI=false;
***************
*** 516,548 ****
public boolean isEnabled() {
return enabled;
}
!
public Dimension getPreferredSize() {
! Graphics g = PropUtils.getScratchGraphics(this);
! FontMetrics fm = g.getFontMetrics(getFont());
! int w;
! if (getText() != null) {
! //avoid NPE in sun.awt.font.FontDesignMetrics.stringWidth():281
! w = fm.stringWidth(getText()) + 4;
! } else {
! w = PropUtils.getMinimumPropPanelWidth();
! }
! int h = fm.getHeight() + 2;
! w = Math.max(w,PropUtils.getMinimumPropPanelWidth());
! h = Math.max(h,PropUtils.getMinimumPropPanelHeight());
! Dimension result = new Dimension(w,h);
! if (getIcon() != null) {
! result.height = Math.max (result.height, getIcon().getIconHeight());
! result.width += getIcon().getIconHeight();
! }
! if (getBorder() != null) {
! Insets i = getBorder().getBorderInsets(this);
! result.width += i.right+i.left;
! result.height += i.top+i.bottom;
! }
return result;
}
!
public void paint (Graphics g) {
if (editor != null) {
setEnabled(PropUtils.checkEnabled (this, editor, env));
--- 507,524 ----
public boolean isEnabled() {
return enabled;
}
!
public Dimension getPreferredSize() {
! Dimension result = super.getPreferredSize();
! result.width = Math.max(result.width,
! PropUtils.getMinimumPropPanelWidth());
!
! result.height = Math.max(result.height,
! PropUtils.getMinimumPropPanelHeight());
!
return result;
}
!
public void paint (Graphics g) {
if (editor != null) {
setEnabled(PropUtils.checkEnabled (this, editor, env));
***************
*** 557,562 ****
--- 533,539 ----
}
clear();
}
+
private void delegatedPaint (Graphics g) {
Color c = g.getColor();
***************
*** 572,577 ****
--- 549,556 ----
b.paintBorder(this, g, 0, 0, getWidth(), getHeight());
}
Rectangle r = getBounds();
+ //XXX May be the source of Rochelle's multiple rows of error
+ //marking misalignment problem...(I do not jest)
r.x = getWidth() > 16 ? editor instanceof Boolean3WayEditor ? 0 : 3 : 0; //align text with other renderers
r.width -= getWidth() > 16 ? editor instanceof Boolean3WayEditor ? 0 : 3 : 0; //align text with other renderers
r.y = 0;
***************
*** 584,607 ****
public void clear() {
editor = null;
env = null;
! setText(""); //NOI18N
setIcon(null);
setOpaque(true);
}
public void setValue(Object o) {
! super.setValue(o);
}
- public void setText(String s) {
- //XXX hotfix for the form editor until the HTML renderer can
- //be put into trunk - per Trung's request
- super.setText(stripHTML(s));
- }
-
public void connect(PropertyEditor p, PropertyEnv env) {
editor = p;
this.env = env;
reset();
}
--- 563,583 ----
public void clear() {
editor = null;
env = null;
! setText("", null); //NOI18N
setIcon(null);
setOpaque(true);
}
+ private Object value = null;
public void setValue(Object o) {
! value = o;
! setText (value instanceof String ? (String) value : value != null ? value.toString() : null);
}
public void connect(PropertyEditor p, PropertyEnv env) {
editor = p;
this.env = env;
+ setRenderStyle(STYLE_TRUNCATE);
reset();
}
***************
*** 664,670 ****
}
public boolean supportsTextEntry() {
! return true;
}
/** Overridden to do nothing */
--- 640,646 ----
}
public boolean supportsTextEntry() {
! return false;
}
/** Overridden to do nothing */
***************
*** 675,712 ****
protected void fireStateChanged() {
}
- /** Overridden to do nothing */
- protected void firePropertyChange(String name, Object old, Object nue) {
- }
-
- /** Overridden to do nothing */
- public void firePropertyChange(String name, boolean old, boolean nue) {
- }
-
- /** Overridden to do nothing */
- public void firePropertyChange(String name, int old, int nue) {
- }
-
- /** Overridden to do nothing */
- public void firePropertyChange(String name, byte old, byte nue) {
- }
-
- /** Overridden to do nothing */
- public void firePropertyChange(String name, char old, char nue) {
- }
-
- /** Overridden to do nothing */
- public void firePropertyChange(String name, double old, double nue) {
- }
-
- /** Overridden to do nothing */
- public void firePropertyChange(String name, float old, float nue) {
- }
-
- /** Overridden to do nothing */
- public void firePropertyChange(String name, short old, short nue) {
- }
-
public void addActionListener(ActionListener al) {
//do nothing
}
--- 651,656 ----
***************
*** 1054,1060 ****
}
}
!
public static boolean requiresSwingPainting (Component c) {
if (!(c instanceof InplaceEditor)) {
return true;
--- 998,1004 ----
}
}
! /*
public static boolean requiresSwingPainting (Component c) {
if (!(c instanceof InplaceEditor)) {
return true;
***************
*** 1115,1118 ****
--- 1059,1063 ----
return s;
}
}
+ */
}
Index: openide/src/org/openide/explorer/propertysheet/SheetCellRenderer.java
===================================================================
RCS file: /cvs/openide/src/org/openide/explorer/propertysheet/SheetCellRenderer.java,v
retrieving revision 1.8
diff -c -r1.8 SheetCellRenderer.java
*** openide/src/org/openide/explorer/propertysheet/SheetCellRenderer.java 21 Jan 2004 20:36:53 -0000 1.8
--- openide/src/org/openide/explorer/propertysheet/SheetCellRenderer.java 9 Mar 2004 23:28:12 -0000
***************
*** 21,28 ****
import java.beans.FeatureDescriptor;
import javax.swing.*;
import javax.swing.table.TableCellRenderer;
! import javax.swing.table.DefaultTableCellRenderer;
import org.openide.nodes.Node.*;
/** An implementation of SheetCellRenderer that wraps custom InplaceEditors
* to efficiently render properties.
*
--- 21,29 ----
import java.beans.FeatureDescriptor;
import javax.swing.*;
import javax.swing.table.TableCellRenderer;
! import org.openide.awt.HtmlRenderer;
import org.openide.nodes.Node.*;
+
/** An implementation of SheetCellRenderer that wraps custom InplaceEditors
* to efficiently render properties.
*
***************
*** 69,81 ****
if (fd instanceof PropertySet) {
SetRenderer sr = getSetRenderer();
! sr.setText(fd.getDisplayName());
sr.setExpanded(((SheetTable) table).getPropertySetModel().isExpanded(fd));
result = sr;
} else {
if (column == 0) {
! JLabel lbl = factory().getStringRenderer();
! lbl.setText(fd.getDisplayName());
if (includeMargin) {
lbl.setBorder(BorderFactory.createEmptyBorder(
0, PropUtils.getMarginWidth() + 2, 0, 1));
--- 70,100 ----
if (fd instanceof PropertySet) {
SetRenderer sr = getSetRenderer();
! String txt = ((PropertySet) fd).getHtmlDisplayName();
! boolean isHtml = txt != null;
! if (!isHtml) {
! txt = fd.getDisplayName();
! }
!
! ((HtmlRenderer)sr).setText (txt, isHtml ? Boolean.TRUE :
! Boolean.FALSE);
!
sr.setExpanded(((SheetTable) table).getPropertySetModel().isExpanded(fd));
+
result = sr;
} else {
if (column == 0) {
!
!
! String txt = ((Property) fd).getHtmlDisplayName();
! boolean isHtml = txt != null;
! if (!isHtml) {
! txt = fd.getDisplayName();
! }
! HtmlRenderer lbl = HtmlRenderer.sharedInstance(isHtml);
!
! lbl.setText (txt, isHtml ? Boolean.TRUE : Boolean.FALSE);
!
if (includeMargin) {
lbl.setBorder(BorderFactory.createEmptyBorder(
0, PropUtils.getMarginWidth() + 2, 0, 1));
***************
*** 98,111 ****
result = lbl;
} else {
result = factory().getRenderer((Property) fd);
- //Use a 2 pixel margin so it's not flush
- /*
- ((JComponent)result).setBorder(BorderFactory.createEmptyBorder(0,
- PropUtils.getTextMargin(), 0, 0));
- */
}
}
- // result.setFont(table.getFont());
return result;
}
--- 117,124 ----
***************
*** 124,140 ****
* and paint it across two columns after the rest of the paint cycle
* is completed.
*/
! static class SetRenderer extends DefaultTableCellRenderer {
!
public boolean dontPaint = true;
- int textY = -1;
- int iconY = -1;
/** Discard/recalc UI dependent values */
public void updateUI() {
super.updateUI();
! iconY=-1;
! textY=-1;
}
private boolean expanded;
--- 137,150 ----
* and paint it across two columns after the rest of the paint cycle
* is completed.
*/
! static class SetRenderer extends HtmlRenderer {
! Insets insets;
public boolean dontPaint = true;
/** Discard/recalc UI dependent values */
public void updateUI() {
super.updateUI();
! insets = new Insets(0, PropUtils.getIconMargin(), 0, 0);
}
private boolean expanded;
***************
*** 147,168 ****
PropUtils.getCollapsedIcon();
}
! /** Calculate y position to center text and icon vertically */
! private void calcYPos(FontMetrics fm) {
! int h = getHeight();
! int ih = getIcon().getIconHeight();
! int fh = fm.getHeight();
! if (fh >= h) {
! textY = 0 + fm.getAscent();
! } else {
! textY = ((h - fh) / 2) + fm.getAscent();
! }
!
! if (ih >= h) {
! iconY = 0;
! } else {
! iconY = (h - ih) / 2;
! }
}
/** Paint the component, if the dontPaint
field is
--- 157,168 ----
PropUtils.getCollapsedIcon();
}
! public Insets getInsets() {
! return insets;
! }
!
! public int getIconTextGap() {
! return 2; //PropUtils.getMarginWidth() + 2;
}
/** Paint the component, if the dontPaint
field is
***************
*** 173,187 ****
*/
public void paint(Graphics g) {
if (!dontPaint) {
! if (iconY == -1) calcYPos(g.getFontMetrics(getFont()));
! g.setFont(getFont());
! g.setColor(getBackground());
! g.fillRect(0,0,getWidth(),getHeight());
! Icon ic = getIcon();
! ic.paintIcon(this, g, PropUtils.getIconMargin(), iconY);
! g.setColor(getForeground());
! g.drawString(getText(), PropUtils.getIconMargin()+ PropUtils.getMarginWidth() + 2, //XXX text icon gap
! textY);
}
}
/** Overridden to do nothing */
--- 173,179 ----
*/
public void paint(Graphics g) {
if (!dontPaint) {
! super.paint(g);
}
}
/** Overridden to do nothing */
***************
*** 190,199 ****
/** Overridden to do nothing */
protected void fireStateChanged() {
- }
-
- /** Overridden to do nothing */
- protected void firePropertyChange(String name, Object old, Object nue) {
}
}
}
--- 182,187 ----
Index: openide/src/org/openide/explorer/view/ListViewDropSupport.java
===================================================================
RCS file: /cvs/openide/src/org/openide/explorer/view/ListViewDropSupport.java,v
retrieving revision 1.16
diff -c -r1.16 ListViewDropSupport.java
*** openide/src/org/openide/explorer/view/ListViewDropSupport.java 21 Nov 2003 09:05:25 -0000 1.16
--- openide/src/org/openide/explorer/view/ListViewDropSupport.java 9 Mar 2004 23:28:13 -0000
***************
*** 53,61 ****
/** The component we are supporting with drop support */
protected JList list;
- /** For managing visual appearance of JList cells. */
- protected NodeRenderer.List cellRenderer;
-
// Operations
public ListViewDropSupport (ListView view, JList list) {
this( view, list, true );
--- 53,58 ----
***************
*** 66,72 ****
{
this.view = view;
this.list = list;
- //cellRenderer = (NodeListCellRenderer)list.getCellRenderer();
this.dropTargetPopupAllowed = dropTargetPopupAllowed;
}
--- 63,68 ----
***************
*** 265,277 ****
}
return dropTarget;
}
-
- /** Safe getter for the cell renderer of asociated list */
- NodeRenderer.List getCellRenderer () {
- if (cellRenderer == null)
- cellRenderer = (NodeRenderer.List)list.getCellRenderer();
- return cellRenderer;
- }
-
-
}
--- 261,264 ----
Index: openide/src/org/openide/explorer/view/NodeRenderer.java
===================================================================
RCS file: /cvs/openide/src/org/openide/explorer/view/NodeRenderer.java,v
retrieving revision 1.28
diff -c -r1.28 NodeRenderer.java
*** openide/src/org/openide/explorer/view/NodeRenderer.java 25 Feb 2004 01:08:43 -0000 1.28
--- openide/src/org/openide/explorer/view/NodeRenderer.java 9 Mar 2004 23:28:18 -0000
***************
*** 36,45 ****
--- 36,47 ----
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.WeakHashMap;
+ import javax.swing.Icon;
import javax.swing.JRootPane;
import javax.swing.SwingUtilities;
import org.openide.ErrorManager;
+ import org.openide.awt.HtmlRenderer;
import org.openide.nodes.Node;
import org.openide.util.Utilities;
***************
*** 49,55 ****
*
* @see org.openide.nodes.Node
*
! * @author Jaroslav Tulach
*/
public class NodeRenderer extends Object
implements TreeCellRenderer, ListCellRenderer {
--- 51,57 ----
*
* @see org.openide.nodes.Node
*
! * @author Jaroslav Tulach, Tim Boudreau
*/
public class NodeRenderer extends Object
implements TreeCellRenderer, ListCellRenderer {
***************
*** 59,71 ****
/** Flag indicating if to use big icons. */
private boolean bigIcons;
- static Border emptyBorder = BorderFactory.createEmptyBorder (1, 1, 1, 1);
-
/** Creates default renderer. */
public NodeRenderer () {
}
-
/** Creates renderer.
* @param bigIcons use big icons if possible
*/
--- 61,70 ----
***************
*** 82,91 ****
return sharedInstance;
}
-
- //
- // Rendering methods
- //
/** Finds the component that is capable of drawing the cell in a tree.
* @param value value can be either Node
--- 81,86 ----
***************
*** 97,489 ****
boolean sel, boolean expanded,
boolean leaf, int row, boolean hasFocus
) {
! return getTree().getTreeCellRendererComponent (
! tree, value, sel, expanded, leaf, row, hasFocus
! );
}
!
!
/** This is the only method defined by ListCellRenderer
. We just
* reconfigure the Jlabel
each time we're called.
*/
public Component getListCellRendererComponent (
! JList list,
! Object value, // value to display
! int index, // cell index
! boolean isSelected, // is the cell selected
! boolean cellHasFocus // the list and the cell have the focus
! ) {
! // accepting either Node or Visualizers
! VisualizerNode vis = (value instanceof Node) ?
! VisualizerNode.getVisualizer (null, (Node)value)
! :
! (VisualizerNode)value;
! if (vis == null) {
! vis = VisualizerNode.EMPTY;
}
- ListCellRenderer r = bigIcons ? (ListCellRenderer)getPane() : getList();
-
- Component result = r.getListCellRendererComponent (
- list, vis, index, isSelected, cellHasFocus
- );
- result.setFont(list.getFont());
return result;
}
!
! // ********************
! // Support for dragging
! // ********************
!
! /** Value of the cell with 'drag under' visual feedback */
! private static VisualizerNode draggedOver;
!
!
! /** DnD operation enters. Update look and feel to the 'drag under' state.
! * @param value the value of cell which should have 'drag under' visual feedback
! */
! static void dragEnter (Object dragged) {
! draggedOver = (VisualizerNode)dragged;
! }
!
! /** DnD operation exits. Revert to the normal look and feel. */
! static void dragExit () {
! draggedOver = null;
! }
!
!
! // ********************
! // Cache for ImageIcons
! // ********************
!
! /** default icon to use when none is present */
! private static final String DEFAULT_ICON = "org/openide/resources/defaultNode.gif"; // NOI18N
!
! /** loaded default icon */
! private static ImageIcon defaultIcon;
!
! /** of icons used (Image, IconImage)*/
! private static final WeakHashMap map = new WeakHashMap ();
!
! /** Loades default icon if not loaded. */
! static ImageIcon getDefaultIcon () {
! if (defaultIcon == null) {
! defaultIcon = new ImageIcon(Utilities.loadImage(DEFAULT_ICON));
! }
!
! return defaultIcon;
! }
!
! /** Finds imager for given resource.
! * @param image image to get
! * @return icon for the image
! */
! static ImageIcon getIcon (Image image) {
! Reference ref = (Reference)map.get (image);
!
! ImageIcon icon = ref == null ? null : (ImageIcon)ref.get ();
! if (icon != null) {
! return icon;
! }
!
! icon = new ImageIcon (image);
! map.put (image, new WeakReference (icon));
!
! return icon;
! }
!
! //
! // Renderers
! //
!
!
! private static NodeRenderer.Tree tree = null;
!
! private synchronized static NodeRenderer.Tree getTree () {
! if (tree == null)
! tree = new NodeRenderer.Tree ();
! return tree;
! }
!
! private static NodeRenderer.Pane pane = null;
!
! private synchronized static NodeRenderer.Pane getPane() {
! if (pane == null)
! pane = new NodeRenderer.Pane ();
! return pane;
! }
!
! private static NodeRenderer.List list = null;
!
! private synchronized static NodeRenderer.List getList() {
! if (list == null)
! list = new NodeRenderer.List ();
! return list;
! }
!
!
! /** Tree cell renderer. Accepts only VisualizerNode
values. */
! final static class Tree extends DefaultTreeCellRenderer {
! /** generated Serialized Version UID */
! static final long serialVersionUID = -183570483117501696L;
!
! /** @return Rendered cell component */
! public Component getTreeCellRendererComponent(
! JTree tree, Object value,
! boolean sel, boolean expanded,
! boolean leaf, int row, boolean hasFocus
! ) {
! setEnabled(tree.isEnabled());
! // accepts only VisualizerNode
! VisualizerNode vis = (VisualizerNode)value;
!
! Image iconImg;
! if (expanded) {
! iconImg = vis.node.getOpenedIcon(BeanInfo.ICON_COLOR_16x16);
! } else {
! iconImg = vis.node.getIcon(BeanInfo.ICON_COLOR_16x16);
! }
- // bugfix #28515, check if getIcon contract isn't broken
- if (iconImg == null) {
- String method = expanded ? "getOpenedIcon" : "getIcon"; // NOI18N
- ErrorManager.getDefault ().log (ErrorManager.WARNING, "Node \"" + vis.node.getName () + // NOI18N
- "\" [" +vis.node.getClass().getName()+ "] cannot return null from " + method + "(). See Node." + method + " contract."); // NOI18N
- } else {
- ImageIcon nodeicon = NodeRenderer.getIcon(iconImg);
-
- setIconTextGap (4 - nodeicon.getIconWidth()
- + ( nodeicon.getIconWidth() > 24 ? nodeicon.getIconWidth() : 24 ) );
- setIcon(nodeicon);
- }
-
- setText(vis.getDisplayName ());
-
- // provide "drag under" feedback if DnD operation is active // NOI18N
- if (vis == draggedOver) {
- sel = true;
- }
-
- this.hasFocus = hasFocus;
- selected = sel;
-
-
if (sel) {
//Find out who has focus
Component focusOwner =
KeyboardFocusManager.getCurrentKeyboardFocusManager().
getPermanentFocusOwner();
!
! boolean treeHasFocus = focusOwner == tree ||
! tree.isAncestorOf(focusOwner) || focusOwner instanceof TreeTable;
if (!treeHasFocus) {
! TreeTable tt = (TreeTable)SwingUtilities.getAncestorOfClass(TreeTable.class, focusOwner);
if (tt != null) {
! treeHasFocus = focusOwner != null &&
! tt.getDefaultRenderer(TreeTableModelAdapter.class)
! == tree;
}
}
-
- setBackgroundSelectionColor(treeHasFocus ?
- UIManager.getColor("Tree.selectionBackground") :
- getNoFocusSelectionBackground()); //NOI18N
-
- setForeground(treeHasFocus ?
- UIManager.getColor("Tree.selectionForeground") :
- getNoFocusSelectionForeground()); //NOI18N
- } else {
- setForeground(getTextNonSelectionColor());
- setBackground(tree.getBackground());
}
!
! return this;
! }
!
! protected void firePropertyChange(String name, Object old, Object nw) {
! // do really nothing!
! }
!
! } // End of class Tree.
!
!
! /** Implements a ListCellRenderer
for rendering items
! * of a List
containing Node
s.
! * It displays the node's 16x16 icon and its display name.
! *
! * @author Ian Formanek
! */
! static final class List extends JLabel implements ListCellRenderer {
! /** generated Serialized Version UID */
! static final long serialVersionUID = -8387317362588264203L;
!
! /** Focused Node border. */
! protected static Border focusBorder = BorderFactory.createLineBorder (
! UIManager.getColor ("List.focusCellHighlight") != null ?
! UIManager.getColor ("List.focusCellHighlight") : Color.blue); // NOI18N
!
! public List() {
! setOpaque(true);
! }
!
! /** This is the only method defined by ListCellRenderer. We just
! * reconfigure the Jlabel each time we're called.
! */
! public Component getListCellRendererComponent (
! JList list,
! Object value, // value to display
! int index, // cell index
! boolean isSelected, // is the cell selected
! boolean cellHasFocus) // the list and the cell have the focus
! {
! VisualizerNode vis = (VisualizerNode)value;
! ImageIcon nodeicon = NodeRenderer.getIcon(vis.node.getIcon(BeanInfo.ICON_COLOR_16x16));
! setIcon(nodeicon);
! setText(vis.getDisplayName ());
! if (isSelected) {
! Component focusOwner =
! KeyboardFocusManager.getCurrentKeyboardFocusManager().
! getPermanentFocusOwner();
!
! boolean hasFocus = focusOwner == list || list.isAncestorOf(focusOwner);
!
! setBackground(hasFocus ? list.getSelectionBackground() :
! getNoFocusSelectionBackground());
!
! setForeground(hasFocus ? list.getSelectionForeground() :
! getNoFocusSelectionForeground());
! } else {
! setBackground(list.getBackground());
! setForeground(list.getForeground());
}
-
- setIconTextGap (4 - nodeicon.getIconWidth()
- + ( nodeicon.getIconWidth() > 24 ? nodeicon.getIconWidth() : 24 ) );
-
-
- int delta = NodeListModel.findVisualizerDepth (list.getModel (), vis);
-
- Border border = (cellHasFocus || value == draggedOver) ? focusBorder : emptyBorder;
- if (delta > 0) {
- border = BorderFactory.createCompoundBorder (
- BorderFactory.createEmptyBorder (0, nodeicon.getIconWidth() * delta, 0, 0),
- border
- );
- }
- setBorder(border);
-
- return this;
}
!
! protected void firePropertyChange(String name, Object old, Object nw) {
! // do really nothing!
! }
!
! } // End of class List.
!
!
! /** List cell renderer which renders icon and display name from VisualizerNode
. */
! final static class Pane extends JLabel implements ListCellRenderer {
! /** generated Serialized Version UID */
! static final long serialVersionUID = -5100925551665387243L;
!
! /** Focused Node border. */
! static Border focusBorder = LineBorder.createBlackLineBorder();
!
! /** Creates a new NetbeansListCellRenderer */
! public Pane () {
! setOpaque(true);
! setVerticalTextPosition(JLabel.BOTTOM);
! setHorizontalAlignment(JLabel.CENTER);
! setHorizontalTextPosition(JLabel.CENTER);
! }
!
! /** This is the only method defined by ListCellRenderer. We just
! * reconfigure the Jlabel each time we're called.
! * @param list the JList
! * @param value the value returned by list.getModel().getElementAt(index)
! * @param index the cells index
! * @param isSelected true
if the specified cell was selected
! * @param cellHasFocus true
if the specified cell has the focus
! * @return a component whose paint() method will render the specified value
! */
! public Component getListCellRendererComponent (
! JList list, Object value, int index,
! boolean isSelected, boolean cellHasFocus
! ) {
! VisualizerNode vis = (VisualizerNode)value;
!
! setIcon(NodeRenderer.getIcon(vis.node.getIcon(BeanInfo.ICON_COLOR_32x32)));
! setText(vis.getDisplayName ());
! Component focusOwner =
! KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
! boolean hasFocus = focusOwner == list ||
! list.isAncestorOf(focusOwner);
!
! if (isSelected){
! setBackground(hasFocus ? list.getSelectionBackground()
! : getNoFocusSelectionBackground());
!
! setForeground(hasFocus ? list.getSelectionForeground() :
! getNoFocusSelectionForeground());
}
! else {
! setBackground(list.getBackground());
! setForeground(list.getForeground());
! }
!
! setBorder(cellHasFocus ? focusBorder : emptyBorder);
! return this;
! }
!
! protected void firePropertyChange(String name, Object old, Object nw) {
! // do really nothing!
! }
! } // End of class Pane.
! private static Color noFocusSelectionBackground=null;
! static Color getNoFocusSelectionBackground() {
! if (noFocusSelectionBackground == null) {
! //allow theme/ui custom definition
! noFocusSelectionBackground =
! UIManager.getColor("nb.explorer.noFocusSelectionBackground"); //NOI18N
! if (noFocusSelectionBackground == null) {
! //try to get standard shadow color
! noFocusSelectionBackground = UIManager.getColor("controlShadow"); //NOI18N
! if (noFocusSelectionBackground == null) {
! //Okay, the look and feel doesn't suport it, punt
! noFocusSelectionBackground = Color.lightGray;
! }
! //Lighten it a bit because disabled text will use controlShadow/
! //gray
! noFocusSelectionBackground = noFocusSelectionBackground.brighter();
! }
! }
! return noFocusSelectionBackground;
}
!
! private static Color noFocusSelectionForeground=null;
! static Color getNoFocusSelectionForeground() {
! if (noFocusSelectionForeground == null) {
! //allow theme/ui custom definition
! noFocusSelectionForeground =
! UIManager.getColor("nb.explorer.noFocusSelectionForeground"); //NOI18N
! if (noFocusSelectionForeground == null) {
! //try to get standard shadow color
! noFocusSelectionForeground = UIManager.getColor("textText"); //NOI18N
! if (noFocusSelectionForeground == null) {
! //Okay, the look and feel doesn't suport it, punt
! noFocusSelectionForeground = Color.BLACK;
! }
! }
! }
! return noFocusSelectionForeground;
}
!
!
}
--- 92,261 ----
boolean sel, boolean expanded,
boolean leaf, int row, boolean hasFocus
) {
! VisualizerNode vis = findVisualizerNode (value);
!
! String text = vis.getHtmlDisplayName();
! boolean isHtml = text != null;
! if (!isHtml) {
! text = vis.getDisplayName();
! }
!
! HtmlRenderer ren = HtmlRenderer.sharedInstance(isHtml);
!
! //Get our result value - really it is ren, but this call causes
! //it to configure itself with the passed values
! Component result = ren.getTreeCellRendererComponent(
! tree, text, sel, expanded, leaf, row, hasFocus);
!
! //Do our additional configuration - set up the icon and possibly
! //do some hacks to make it look focused for TreeTableView
! configureFrom (ren, value, tree, expanded, sel, vis);
!
! return result;
}
!
/** This is the only method defined by ListCellRenderer
. We just
* reconfigure the Jlabel
each time we're called.
*/
public Component getListCellRendererComponent (
! JList list, Object value, int index, boolean sel,
! boolean cellHasFocus) {
!
! VisualizerNode vis = findVisualizerNode(value);
! String text = vis.getHtmlDisplayName();
! boolean isHtml = text != null;
! if (!isHtml) {
! text = vis.getDisplayName();
! }
!
! HtmlRenderer ren = HtmlRenderer.sharedInstance(isHtml);
!
! //Get our result value - really it is ren, but this call causes
! //it to configure itself with the passed values
! Component result = ren.getListCellRendererComponent(
! list, text, index, sel, cellHasFocus || value == draggedOver);
!
! //Do our additional configuration - set up the icon and possibly
! //do some hacks to make it look focused for TreeTableView
! configureFrom (ren, value, list, false, sel, vis);
!
! if (bigIcons) {
! ren.setCentered(true);
! } else if (ren.getIcon() != null) {
! //copied from original - not quite sure how this does what it does,
! //but it does something
! int indent = ren.getIcon().getIconWidth() *
! NodeListModel.findVisualizerDepth (list.getModel (), vis);
!
! ren.setIndent (indent);
}
return result;
}
!
! /** Utility method which performs configuration which is common to all of the renderer
! * implementations - sets the icon and focus properties on the renderer
! * from the VisualizerNode. */
! private static void configureFrom (HtmlRenderer ren, Object value, Container
! target, boolean useOpenedIcon, boolean sel, VisualizerNode vis) {
!
! Icon icon = vis.getIcon(useOpenedIcon);
!
! if (icon.getIconWidth() > 0) {
! //Max annotated icon width is 24, so to have all the text and all
! //the icons come out aligned, set the icon text gap to the difference
! //plus a two pixel margin
! ren.setIconTextGap (26 - icon.getIconWidth());
! //Add a 2 pixel border so it's not flush, with an extra two pixel
! //margin at the top and bottom
! } else {
! //If the icon width is 0, fill the space using a border, and add in
! //the extra two pixels so the node names are aligned (btw, this
! //does seem to waste a frightful amount of horizontal space in
! //a tree that can use all it can get)
! ren.setBorder (BorderFactory.createEmptyBorder(
! 0,
! 26,
! 0,
! 0));
! }
! //Inscrutable original code
! /*
! if (icon.getIconWidth() > 24) {
! iconTextGap = 4 - icon.getIconWidth() +
! (icon.getIconWidth() > 24 ? icon.getIconWidth() : 24 );
! }
! */
!
! ren.setIcon (icon);
!
! //Do the kooky focus dance so the tree that is a renderer for
! //TreeTableView will paint as though focused even though it's
! //never onscreen.
! if (target instanceof JTree) {
! boolean treeHasFocus = false;
if (sel) {
//Find out who has focus
Component focusOwner =
KeyboardFocusManager.getCurrentKeyboardFocusManager().
getPermanentFocusOwner();
!
! treeHasFocus = focusOwner == target ||
! target.isAncestorOf(focusOwner) || focusOwner
! instanceof TreeTable;
if (!treeHasFocus) {
! TreeTable tt = (TreeTable)SwingUtilities.getAncestorOfClass(
! TreeTable.class, focusOwner);
!
if (tt != null) {
! treeHasFocus = focusOwner != null &&
! tt.getDefaultRenderer(TreeTableModelAdapter.class)
! == target;
}
}
}
! if (treeHasFocus) {
! ren.setPaintAsFocused(true);
}
}
! ren.setFont(target.getFont());
! }
!
! /** Utility method to find a visualizer node for the object passed to
! * any of the cell renderer methods as the value */
! private static final VisualizerNode findVisualizerNode(Object value) {
! VisualizerNode vis = (value instanceof Node) ?
! VisualizerNode.getVisualizer (null, (Node) value) :
! (VisualizerNode)value;
! if (vis == null) {
! vis = VisualizerNode.EMPTY;
}
!
! return vis;
! }
!
! // ********************
! // Support for dragging
! // ********************
! /** Value of the cell with 'drag under' visual feedback */
! private static VisualizerNode draggedOver;
! /** DnD operation enters. Update look and feel to the 'drag under' state.
! * @param value the value of cell which should have 'drag under' visual feedback
! */
! static void dragEnter (Object dragged) {
! draggedOver = (VisualizerNode)dragged;
}
!
! /** DnD operation exits. Revert to the normal look and feel. */
! static void dragExit () {
! draggedOver = null;
}
!
}
Index: openide/src/org/openide/explorer/view/TableSheetCell.java
===================================================================
RCS file: /cvs/openide/src/org/openide/explorer/view/TableSheetCell.java,v
retrieving revision 1.18
diff -c -r1.18 TableSheetCell.java
*** openide/src/org/openide/explorer/view/TableSheetCell.java 17 Feb 2004 16:47:49 -0000 1.18
--- openide/src/org/openide/explorer/view/TableSheetCell.java 9 Mar 2004 23:28:19 -0000
***************
*** 259,269 ****
propPanel.setBackground(tableHasFocus ?
table.getSelectionBackground() :
! NodeRenderer.getNoFocusSelectionBackground());
propPanel.setForeground(tableHasFocus ?
table.getSelectionForeground() :
! NodeRenderer.getNoFocusSelectionForeground());
} else {
propPanel.setBackground(table.getBackground());
--- 259,269 ----
propPanel.setBackground(tableHasFocus ?
table.getSelectionBackground() :
! TreeTable.getUnfocusedSelectedBackground());
propPanel.setForeground(tableHasFocus ?
table.getSelectionForeground() :
! TreeTable.getUnfocusedSelectedForeground());
} else {
propPanel.setBackground(table.getBackground());
***************
*** 289,296 ****
((Container) focusOwner).isAncestorOf(table));
nullPanel.setBackground(tableHasFocus ?
! table.getSelectionBackground() :
! NodeRenderer.getNoFocusSelectionBackground());
//XXX may want to handle inverse theme here and use brighter if
//below a threshold. Deferred to centralized color management
//being implemented.
--- 289,296 ----
((Container) focusOwner).isAncestorOf(table));
nullPanel.setBackground(tableHasFocus ?
! table.getSelectionBackground() :
! TreeTable.getUnfocusedSelectedBackground());
//XXX may want to handle inverse theme here and use brighter if
//below a threshold. Deferred to centralized color management
//being implemented.
Index: openide/src/org/openide/explorer/view/TreeTable.java
===================================================================
RCS file: /cvs/openide/src/org/openide/explorer/view/TreeTable.java,v
retrieving revision 1.46
diff -c -r1.46 TreeTable.java
*** openide/src/org/openide/explorer/view/TreeTable.java 2 Mar 2004 19:06:13 -0000 1.46
--- openide/src/org/openide/explorer/view/TreeTable.java 9 Mar 2004 23:28:23 -0000
***************
*** 703,714 ****
focusOwner == TreeTable.this
|| TreeTable.this.isAncestorOf(focusOwner);
setBackground(tableHasFocus ?
table.getSelectionBackground() :
! NodeRenderer.getNoFocusSelectionBackground());
setForeground(tableHasFocus ?
table.getSelectionForeground() :
! NodeRenderer.getNoFocusSelectionForeground());
} else {
setBackground(table.getBackground());
setForeground(table.getForeground());
--- 703,718 ----
focusOwner == TreeTable.this
|| TreeTable.this.isAncestorOf(focusOwner);
+ //TODO - it should be possible to simply set the correct
+ //color in prepareRenderer for the tree's cell renderer,
+ //rather than set it for the whole tree. Might fix a
+ //couple problems. -Tim
setBackground(tableHasFocus ?
table.getSelectionBackground() :
! getUnfocusedSelectedBackground());
setForeground(tableHasFocus ?
table.getSelectionForeground() :
! getUnfocusedSelectedForeground());
} else {
setBackground(table.getBackground());
setForeground(table.getForeground());
***************
*** 818,827 ****
if (isEditing() && editorComp != null) {
editorComp.setBackground(focused ?
getSelectionBackground() :
! NodeRenderer.getNoFocusSelectionBackground());
editorComp.setForeground(focused ?
getSelectionForeground() :
! NodeRenderer.getNoFocusSelectionForeground());
}
}
--- 822,831 ----
if (isEditing() && editorComp != null) {
editorComp.setBackground(focused ?
getSelectionBackground() :
! getUnfocusedSelectedBackground());
editorComp.setForeground(focused ?
getSelectionForeground() :
! getUnfocusedSelectedForeground());
}
}
***************
*** 1611,1614 ****
--- 1615,1660 ----
}
}
}
+
+ private static Color unfocusedSelBg = null;
+ private static Color unfocusedSelFg = null;
+
+ /** Get the system-wide unfocused selection background color */
+ static Color getUnfocusedSelectedBackground() {
+ if (unfocusedSelBg == null) {
+ //allow theme/ui custom definition
+ unfocusedSelBg =
+ UIManager.getColor("nb.explorer.unfocusedSelBg"); //NOI18N
+ if (unfocusedSelBg == null) {
+ //try to get standard shadow color
+ unfocusedSelBg = UIManager.getColor("controlShadow"); //NOI18N
+ if (unfocusedSelBg == null) {
+ //Okay, the look and feel doesn't suport it, punt
+ unfocusedSelBg = Color.lightGray;
+ }
+ //Lighten it a bit because disabled text will use controlShadow/
+ //gray
+ unfocusedSelBg = unfocusedSelBg.brighter();
+ }
+ }
+ return unfocusedSelBg;
+ }
+
+ /** Get the system-wide unfocused selection foreground color */
+ static Color getUnfocusedSelectedForeground() {
+ if (unfocusedSelFg == null) {
+ //allow theme/ui custom definition
+ unfocusedSelFg =
+ UIManager.getColor("nb.explorer.unfocusedSelFg"); //NOI18N
+ if (unfocusedSelFg == null) {
+ //try to get standard shadow color
+ unfocusedSelFg = UIManager.getColor("textText"); //NOI18N
+ if (unfocusedSelFg == null) {
+ //Okay, the look and feel doesn't suport it, punt
+ unfocusedSelFg = Color.BLACK;
+ }
+ }
+ }
+ return unfocusedSelFg;
+ }
}
Index: openide/src/org/openide/explorer/view/TreeView.java
===================================================================
RCS file: /cvs/openide/src/org/openide/explorer/view/TreeView.java,v
retrieving revision 1.157
diff -c -r1.157 TreeView.java
*** openide/src/org/openide/explorer/view/TreeView.java 8 Mar 2004 15:28:55 -0000 1.157
--- openide/src/org/openide/explorer/view/TreeView.java 9 Mar 2004 23:28:27 -0000
***************
*** 1091,1097 ****
// note: dropTarget is activated in constructor
}
// lazy cell editor init
! tree.setCellEditor(new TreeViewCellEditor(tree, new NodeRenderer.Tree ()));
tree.setEditable(true);
}
--- 1091,1097 ----
// note: dropTarget is activated in constructor
}
// lazy cell editor init
! tree.setCellEditor(new TreeViewCellEditor(tree));
tree.setEditable(true);
}
Index: openide/src/org/openide/explorer/view/TreeViewCellEditor.java
===================================================================
RCS file: /cvs/openide/src/org/openide/explorer/view/TreeViewCellEditor.java,v
retrieving revision 1.37
diff -c -r1.37 TreeViewCellEditor.java
*** openide/src/org/openide/explorer/view/TreeViewCellEditor.java 9 Feb 2004 16:04:19 -0000 1.37
--- openide/src/org/openide/explorer/view/TreeViewCellEditor.java 9 Mar 2004 23:28:28 -0000
***************
*** 46,53 ****
* @param tree the tree
* @param renderer the renderer to use for the cell
*/
! public TreeViewCellEditor(JTree tree, DefaultTreeCellRenderer renderer) {
! super(tree, renderer);
// deal with selection if already exists
if (tree.getSelectionCount() == 1) {
lastPath = tree.getSelectionPath();
--- 46,57 ----
* @param tree the tree
* @param renderer the renderer to use for the cell
*/
! public TreeViewCellEditor(JTree tree) {
! //Use a dummy DefaultTreeCellEditor - we'll set up the correct
! //icon when we fetch the editor component (see EOF). Not sure
! //it's wildly vaulable to subclass DefaultTreeCellEditor here -
! //we override most everything
! super(tree, new DefaultTreeCellRenderer());
// deal with selection if already exists
if (tree.getSelectionCount() == 1) {
lastPath = tree.getSelectionPath();
***************
*** 154,160 ****
}
};
! tf.registerKeyboardAction(
this,
KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, true),
JComponent.WHEN_FOCUSED
--- 158,164 ----
}
};
! tf.registerKeyboardAction( //TODO update to use inputMap/actionMap
this,
KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, true),
JComponent.WHEN_FOCUSED
***************
*** 259,264 ****
--- 263,269 ----
protected void prepareForEditing () {
tree.removeMouseMotionListener (this);
+
super.prepareForEditing ();
}
***************
*** 269,275 ****
}
/** Redefined default cell editor to convert nodes to name */
! static class Ed extends DefaultCellEditor {
/** generated Serialized Version UID */
static final long serialVersionUID = -6373058702842751408L;
--- 274,280 ----
}
/** Redefined default cell editor to convert nodes to name */
! class Ed extends DefaultCellEditor {
/** generated Serialized Version UID */
static final long serialVersionUID = -6373058702842751408L;
***************
*** 289,294 ****
--- 294,301 ----
else
delegate.setValue(""); // NOI18N
+ editingIcon = ((VisualizerNode) value).getIcon(expanded);
+
((JTextField) editorComponent).selectAll();
return editorComponent;
}
Index: openide/src/org/openide/explorer/view/VisualizerNode.java
===================================================================
RCS file: /cvs/openide/src/org/openide/explorer/view/VisualizerNode.java,v
retrieving revision 1.39
diff -c -r1.39 VisualizerNode.java
*** openide/src/org/openide/explorer/view/VisualizerNode.java 20 Jan 2004 15:31:59 -0000 1.39
--- openide/src/org/openide/explorer/view/VisualizerNode.java 9 Mar 2004 23:28:32 -0000
***************
*** 13,21 ****
--- 13,25 ----
package org.openide.explorer.view;
+ import java.awt.Image;
+ import java.beans.BeanInfo;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.*;
+ import javax.swing.Icon;
+ import javax.swing.ImageIcon;
import javax.swing.SwingUtilities;
import javax.swing.event.EventListenerList;
import javax.swing.tree.TreeNode;
***************
*** 23,36 ****
import org.openide.ErrorManager;
import org.openide.nodes.*;
import org.openide.util.Mutex;
import org.openide.util.enum.QueueEnumeration;
/** Visual representation of one node. Holds necessary information about nodes
* like icon, name, description and also list of its children.
* ! * There is at most one VisualizerNode for one node. All of them are hold in a cache. *
! * The VisualizerNode level provides secure layer between Nodes and Swing AWT dispatch * thread. * * @author Jaroslav Tulach --- 27,41 ---- import org.openide.ErrorManager; import org.openide.nodes.*; import org.openide.util.Mutex; + import org.openide.util.Utilities; import org.openide.util.enum.QueueEnumeration; /** Visual representation of one node. Holds necessary information about nodes * like icon, name, description and also list of its children. *
! * There is at most one VisualizerNode for one node. All of them are held in a cache. *
! * The VisualizerNode level provides a thread-safe layer between Nodes and Swing AWT dispatch * thread. * * @author Jaroslav Tulach *************** *** 53,58 **** --- 58,68 ---- private static final QP QUEUE = new QP (); private static final ErrorManager err = ErrorManager.getDefault().getInstance("org.openide.explorer.view.VisualizerNode"); // NOI18N + + /** Cached icon - pre-html, there was a separate cache in NodeRenderer, but + * if we're keeping a weak cache of VisualizerNodes, there's no reason not + * to keep it here */ + private Icon icon = null; // bugfix #29435, getVisualizer is synchronized in place of be called only from EventQueue /** Finds VisualizerNode for given node. *************** *** 391,396 **** --- 401,452 ---- return getDisplayName (); } + public String getHtmlDisplayName() { + return node.getHtmlDisplayName(); + } + + Icon getIcon(boolean opened) { + //XXX - I have moved caching of icons out of NodeRenderer and put it + //here, since there wasn't much sense in having one weak cache of + //icons -> VisualizerNode, and another weak cache of + //VisualizerNode -> Node. However, we should measure this - it may be + //less expensive to create a new ImageIcon every time on the fly than + //to keep a copy of it here. + if (icon == null) { + Image image = opened ? node.getOpenedIcon( + BeanInfo.ICON_COLOR_16x16) : node.getIcon( + BeanInfo.ICON_COLOR_16x16); + + + // bugfix #28515, check if getIcon contract isn't broken + if (image == null) { + String method = opened ? "getOpenedIcon" : "getIcon"; // NOI18N + ErrorManager.getDefault ().log (ErrorManager.WARNING, "Node \"" + + node.getName () + + "\" [" + node.getClass().getName()+ + "] cannot return null from " + method + "(). See Node." + + method + " contract."); // NOI18N + + icon = defaultIcon; + } else { + icon = new ImageIcon (image); + } + } + return icon; + } + + /** loaded default icon */ + private static Icon defaultIcon; + /** default icon to use when none is present */ + private static final String DEFAULT_ICON = "org/openide/resources/defaultNode.gif"; // NOI18N + /** Loads default icon if not loaded. */ + private static Icon getDefaultIcon () { + if (defaultIcon == null) { + defaultIcon = new ImageIcon(Utilities.loadImage(DEFAULT_ICON)); + } + return defaultIcon; + } + /** Strong reference. */ private static final class StrongReference extends WeakReference { Index: openide/src/org/openide/filesystems/FileSystem.java =================================================================== RCS file: /cvs/openide/src/org/openide/filesystems/FileSystem.java,v retrieving revision 1.76 diff -c -r1.76 FileSystem.java *** openide/src/org/openide/filesystems/FileSystem.java 16 Jan 2004 11:16:31 -0000 1.76 --- openide/src/org/openide/filesystems/FileSystem.java 9 Mar 2004 23:28:34 -0000 *************** *** 684,690 **** */ public java.awt.Image annotateIcon (java.awt.Image icon, int iconType, java.util.Set files); } ! /** Empty status */ private static final Status STATUS_NONE = new Status () { public String annotateName (String name, java.util.Set files) { --- 684,717 ---- */ public java.awt.Image annotateIcon (java.awt.Image icon, int iconType, java.util.Set files); } ! ! /** Extension interface for Status provides HTML-formatted annotations. ! * Principally this is used to deëmphasize status text by presenting ! * it in a lighter color, by placing it inside ! * <font color=!controlShadow> tags. Note that it is preferable to ! * use logical colors (such as controlShadow) which are resolved by calling ! * UIManager.getColor(key) — this way they will always fit with the ! * look and feel. To use a logical color, prefix the color name with a ! * ! character. ! *
! * Please use only the limited markup subset of HTML supported by the
! * lightweight HTML renderer.
! * @see org.openide.awt.HtmlRenderer */
! public static interface HtmlStatus extends Status {
! /** Annotate a name such that the returned value contains HTML markup.
! * The return value less the html content should typically be the same
! * as the return value from annotateName()
.
! *
! * For consistency with Node.getHtmlDisplayName()
,
! * filesystems that proxy other filesystems (and so must implement
! * this interface to supply HTML annotations) should return null if
! * the filesystem they proxy does not provide an implementation of
! * HTMLStatus.
! *
! * @see org.openide.awt.HtmlRenderer */
! public String annotateNameHtml (String name, java.util.Set files);
! }
!
/** Empty status */
private static final Status STATUS_NONE = new Status () {
public String annotateName (String name, java.util.Set files) {
Index: openide/src/org/openide/nodes/FilterNode.java
===================================================================
RCS file: /cvs/openide/src/org/openide/nodes/FilterNode.java,v
retrieving revision 1.88
diff -c -r1.88 FilterNode.java
*** openide/src/org/openide/nodes/FilterNode.java 24 Feb 2004 13:34:06 -0000 1.88
--- openide/src/org/openide/nodes/FilterNode.java 9 Mar 2004 23:28:38 -0000
***************
*** 22,27 ****
--- 22,28 ----
import java.util.*;
import java.lang.ref.WeakReference;
+ import java.lang.reflect.Method;
import org.openide.ErrorManager;
import org.openide.util.datatransfer.NewType;
***************
*** 643,648 ****
--- 644,682 ----
}
return retValue;
+ }
+
+ /** Get a display name containing HTML markup. Note: If you subclass
+ * FilterNode and override getDisplayName()
, this method will
+ * always return null unless you override it as well (assuming that if you're
+ * changing the display name, you don't want an HTML display name constructed
+ * from the original node's display name to be what shows up in views of
+ * this node.
+ * @see org.openide.nodes.Node.getHtmlDisplayName
+ * @return An HTML display name, if available, or null if no display name
+ * is available */
+ public String getHtmlDisplayName() {
+ if (overridesGetDisplayName()) {
+ return null;
+ } else {
+ return delegating (DELEGATE_GET_DISPLAY_NAME) ?
+ original.getHtmlDisplayName() : super.getHtmlDisplayName();
+ }
+ }
+
+ private boolean overridesGetDisplayName() {
+ if (getClass() != FilterNode.class) {
+ try {
+ Method m = getClass().getMethod("getDisplayName", null); //NOI18N
+ return m.getDeclaringClass() != FilterNode.class;
+ } catch (NoSuchMethodException nsme) {
+ //can't happen
+ ErrorManager.getDefault().notify(nsme);
+ return true;
+ }
+ } else {
+ return false;
+ }
}
/*
Index: openide/src/org/openide/nodes/Node.java
===================================================================
RCS file: /cvs/openide/src/org/openide/nodes/Node.java,v
retrieving revision 1.78
diff -c -r1.78 Node.java
*** openide/src/org/openide/nodes/Node.java 13 Oct 2003 23:15:28 -0000 1.78
--- openide/src/org/openide/nodes/Node.java 9 Mar 2004 23:28:48 -0000
***************
*** 651,656 ****
--- 651,674 ----
}
}
+ /** Return a variant of the display name containing HTML markup
+ * conforming to the limited subset of font-markup HTML supported by
+ * the lightweight HTML renderer org.openide.awt.HtmlRenderer
+ * (font color, bold, italic and strikethrough supported; font
+ * colors can be UIManager color keys if they are prefixed with
+ * a ! character, i.e. <font color=&'controlShadow'>).
+ * Enclosing html tags are not needed.
+ *
This method should return either an HTML display name
+ * or null; it should not return the non-html display name.
+ *
+ * @see org.openide.awt.HtmlRenderer
+ * @return a String containing conformant, legal HTML markup which
+ * represents the display name, or null. The default implementation
+ * returns null. */
+ public String getHtmlDisplayName() {
+ return null;
+ }
+
/** Register delegating lookup so it can always be found.
*/
final void registerDelegatingLookup (NodeLookup l) {
***************
*** 1007,1012 ****
--- 1025,1048 ----
public int hashCode () {
return getName().hashCode ();
}
+
+ /** Return a variant of the display name containing HTML markup
+ * conforming to the limited subset of font-markup HTML supported by
+ * the lightweight HTML renderer org.openide.awt.HtmlRenderer
+ * (font color, bold, italic and strikethrough supported; font
+ * colors can be UIManager color keys if they are prefixed with
+ * a ! character, i.e. <font color=&'controlShadow'>).
+ * Enclosing html tags are not needed.
+ * This method should return either an HTML display name
+ * or null; it should not return the non-html display name.
+ *
+ * @see org.openide.awt.HtmlRenderer
+ * @return a String containing conformant, legal HTML markup which
+ * represents the display name, or null. The default implementation
+ * returns null. */
+ public String getHtmlDisplayName() {
+ return null;
+ }
}
/** Description of a Bean property on a node, and operations on it.
***************
*** 1151,1156 ****
--- 1187,1210 ----
return getName ().hashCode () *
( valueType == null ? 1 : valueType.hashCode () );
}
+
+ /** Return a variant of the display name containing HTML markup
+ * conforming to the limited subset of font-markup HTML supported by
+ * the lightweight HTML renderer org.openide.awt.HtmlRenderer
+ * (font color, bold, italic and strikethrough supported; font
+ * colors can be UIManager color keys if they are prefixed with
+ * a ! character, i.e. <font color=&'controlShadow'>).
+ * Enclosing html tags are not needed.
+ * This method should return either an HTML display name
+ * or null; it should not return the non-html display name.
+ *
+ * @see org.openide.awt.HtmlRenderer
+ * @return a String containing conformant, legal HTML markup which
+ * represents the display name, or null. The default implementation
+ * returns null. */
+ public String getHtmlDisplayName() {
+ return null;
+ }
}
/** Description of an indexed property and operations on it.
***************
*** 1289,1295 ****
public String toString () {
return super.toString () + "[Name="+getName ()+", displayName="+getDisplayName ()+"]"; // NOI18N
}
-
/** template for changes in cookies */
private static final Lookup.Template TEMPL_COOKIE = new Lookup.Template (Node.Cookie.class);
--- 1343,1348 ----
Index: treefs/src/org/netbeans/modules/treefs/TreeFS.java
===================================================================
RCS file: /cvs/treefs/src/org/netbeans/modules/treefs/TreeFS.java,v
retrieving revision 1.17
diff -c -r1.17 TreeFS.java
*** treefs/src/org/netbeans/modules/treefs/TreeFS.java 5 Sep 2003 01:46:00 -0000 1.17
--- treefs/src/org/netbeans/modules/treefs/TreeFS.java 9 Mar 2004 23:29:12 -0000
***************
*** 48,54 ****
* created is made upon an ExtensionList.
*/
public final class TreeFS extends MultiFileSystem
! implements FileSystem.Status, FileStatusListener, Runnable {
// does not need to be necessarily final
static final long serialVersionUID = -1173676775805432024L;
--- 48,54 ----
* created is made upon an ExtensionList.
*/
public final class TreeFS extends MultiFileSystem
! implements FileSystem.Status, FileStatusListener, Runnable, FileSystem.HtmlStatus {
// does not need to be necessarily final
static final long serialVersionUID = -1173676775805432024L;
***************
*** 431,434 ****
--- 431,452 ----
org.openide.util.RequestProcessor.getDefault ().post (new Fire (), 0, Thread.MIN_PRIORITY);
}
+ /** Proxies implementations of HtmlStatus, returns null if not found */
+ public String annotateNameHtml(String name, java.util.Set files) {
+ if (files.isEmpty()) {
+ //probably the original filesystem was unmounted and this is a
+ //dead TreeFS. Just return the name and get out.
+ return name;
+ }
+ FileObject fo = (FileObject) files.iterator().next();
+ //Get the real underlying filesystem
+ FileSystem fs = findSystem(fo);
+ if (fs.getStatus() instanceof FileSystem.HtmlStatus) {
+ FileSystem.HtmlStatus htmls = (FileSystem.HtmlStatus) fs.getStatus();
+ return htmls.annotateNameHtml(name, translateFiles(fs, files));
+ } else {
+ return null;
+ }
+ }
+
}
Index: vcscore/src/org/netbeans/modules/vcscore/VcsFileSystem.java
===================================================================
RCS file: /cvs/vcscore/src/org/netbeans/modules/vcscore/VcsFileSystem.java,v
retrieving revision 1.250
diff -c -r1.250 VcsFileSystem.java
*** vcscore/src/org/netbeans/modules/vcscore/VcsFileSystem.java 4 Mar 2004 15:23:20 -0000 1.250
--- vcscore/src/org/netbeans/modules/vcscore/VcsFileSystem.java 9 Mar 2004 23:29:49 -0000
***************
*** 103,109 ****
AbstractFileSystem.Change, FileSystem.Status,
CommandExecutionContext, CacheHandlerListener,
FileObjectImportantness, FileObjectExistence,
! VcsOISActivator, Serializable {
public static interface IgnoreListSupport {
--- 103,110 ----
AbstractFileSystem.Change, FileSystem.Status,
CommandExecutionContext, CacheHandlerListener,
FileObjectImportantness, FileObjectExistence,
! VcsOISActivator, Serializable,
! FileSystem.HtmlStatus {
public static interface IgnoreListSupport {
***************
*** 4859,4864 ****
--- 4860,4872 ----
private void D(String debug) {
//System.out.println("VcsFileSystem(): "+debug);
+ }
+
+ public String annotateNameHtml (String name, java.util.Set files) {
+ String result = annotateName (name, files);
+ result = Utilities.replaceString(result, name,
+ name + "") + ""; //NOI18N
+ return result;
}
//-------------------------------------------
}