/*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.swing.tree;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.plaf.FontUIResource;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import java.io.*;
import java.util.EventObject;
import java.util.Vector;
A TreeCellEditor
. You need to supply an
instance of DefaultTreeCellRenderer
so that the icons can be obtained. You can optionally supply
a TreeCellEditor
that will be layed out according
to the icon in the DefaultTreeCellRenderer
.
If you do not supply a TreeCellEditor
,
a TextField
will be used. Editing is started
on a triple mouse click, or after a click, pause, click and
a delay of 1200 milliseconds.
Warning:
Serialized objects of this class will not be compatible with
future Swing releases. The current serialization support is
appropriate for short term storage or RMI between applications running
the same version of Swing. As of 1.4, support for long term storage
of all JavaBeans™
has been added to the java.beans
package. Please see XMLEncoder
.
Author: Scott Violet See Also:
/**
* A <code>TreeCellEditor</code>. You need to supply an
* instance of <code>DefaultTreeCellRenderer</code>
* so that the icons can be obtained. You can optionally supply
* a <code>TreeCellEditor</code> that will be layed out according
* to the icon in the <code>DefaultTreeCellRenderer</code>.
* If you do not supply a <code>TreeCellEditor</code>,
* a <code>TextField</code> will be used. Editing is started
* on a triple mouse click, or after a click, pause, click and
* a delay of 1200 milliseconds.
*<p>
* <strong>Warning:</strong>
* Serialized objects of this class will not be compatible with
* future Swing releases. The current serialization support is
* appropriate for short term storage or RMI between applications running
* the same version of Swing. As of 1.4, support for long term storage
* of all JavaBeans™
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*
* @see javax.swing.JTree
*
* @author Scott Violet
*/
public class DefaultTreeCellEditor implements ActionListener, TreeCellEditor,
TreeSelectionListener {
Editor handling the editing. /** Editor handling the editing. */
protected TreeCellEditor realEditor;
Renderer, used to get border and offsets from. /** Renderer, used to get border and offsets from. */
protected DefaultTreeCellRenderer renderer;
Editing container, will contain the editorComponent
. /** Editing container, will contain the <code>editorComponent</code>. */
protected Container editingContainer;
Component used in editing, obtained from the
editingContainer
.
/**
* Component used in editing, obtained from the
* <code>editingContainer</code>.
*/
transient protected Component editingComponent;
As of Java 2 platform v1.4 this field should no longer be used. If
you wish to provide similar behavior you should directly override
isCellEditable
.
/**
* As of Java 2 platform v1.4 this field should no longer be used. If
* you wish to provide similar behavior you should directly override
* <code>isCellEditable</code>.
*/
protected boolean canEdit;
Used in editing. Indicates x position to place
editingComponent
.
/**
* Used in editing. Indicates x position to place
* <code>editingComponent</code>.
*/
protected transient int offset;
JTree
instance listening too. /** <code>JTree</code> instance listening too. */
protected transient JTree tree;
Last path that was selected. /** Last path that was selected. */
protected transient TreePath lastPath;
Used before starting the editing session. /** Used before starting the editing session. */
protected transient Timer timer;
Row that was last passed into
getTreeCellEditorComponent
.
/**
* Row that was last passed into
* <code>getTreeCellEditorComponent</code>.
*/
protected transient int lastRow;
True if the border selection color should be drawn. /** True if the border selection color should be drawn. */
protected Color borderSelectionColor;
Icon to use when editing. /** Icon to use when editing. */
protected transient Icon editingIcon;
Font to paint with, null
indicates
font of renderer is to be used.
/**
* Font to paint with, <code>null</code> indicates
* font of renderer is to be used.
*/
protected Font font;
Constructs a DefaultTreeCellEditor
object for a JTree using the specified renderer and
a default editor. (Use this constructor for normal editing.)
Params: - tree – a
JTree
object - renderer – a
DefaultTreeCellRenderer
object
/**
* Constructs a <code>DefaultTreeCellEditor</code>
* object for a JTree using the specified renderer and
* a default editor. (Use this constructor for normal editing.)
*
* @param tree a <code>JTree</code> object
* @param renderer a <code>DefaultTreeCellRenderer</code> object
*/
public DefaultTreeCellEditor(JTree tree,
DefaultTreeCellRenderer renderer) {
this(tree, renderer, null);
}
Constructs a DefaultTreeCellEditor
object for a JTree
using the
specified renderer and the specified editor. (Use this constructor
for specialized editing.)
Params: - tree – a
JTree
object - renderer – a
DefaultTreeCellRenderer
object - editor – a
TreeCellEditor
object
/**
* Constructs a <code>DefaultTreeCellEditor</code>
* object for a <code>JTree</code> using the
* specified renderer and the specified editor. (Use this constructor
* for specialized editing.)
*
* @param tree a <code>JTree</code> object
* @param renderer a <code>DefaultTreeCellRenderer</code> object
* @param editor a <code>TreeCellEditor</code> object
*/
public DefaultTreeCellEditor(JTree tree, DefaultTreeCellRenderer renderer,
TreeCellEditor editor) {
this.renderer = renderer;
realEditor = editor;
if(realEditor == null)
realEditor = createTreeCellEditor();
editingContainer = createContainer();
setTree(tree);
setBorderSelectionColor(UIManager.getColor
("Tree.editorBorderSelectionColor"));
}
Sets the color to use for the border.
Params: - newColor – the new border color
/**
* Sets the color to use for the border.
* @param newColor the new border color
*/
public void setBorderSelectionColor(Color newColor) {
borderSelectionColor = newColor;
}
Returns the color the border is drawn.
Returns: the border selection color
/**
* Returns the color the border is drawn.
* @return the border selection color
*/
public Color getBorderSelectionColor() {
return borderSelectionColor;
}
Sets the font to edit with. null
indicates
the renderers font should be used. This will NOT
override any font you have set in the editor
the receiver was instantiated with. If null
for an editor was passed in a default editor will be
created that will pick up this font.
Params: - font – the editing
Font
See Also:
/**
* Sets the font to edit with. <code>null</code> indicates
* the renderers font should be used. This will NOT
* override any font you have set in the editor
* the receiver was instantiated with. If <code>null</code>
* for an editor was passed in a default editor will be
* created that will pick up this font.
*
* @param font the editing <code>Font</code>
* @see #getFont
*/
public void setFont(Font font) {
this.font = font;
}
Gets the font used for editing.
See Also: Returns: the editing Font
/**
* Gets the font used for editing.
*
* @return the editing <code>Font</code>
* @see #setFont
*/
public Font getFont() {
return font;
}
//
// TreeCellEditor
//
Configures the editor. Passed onto the realEditor
.
/**
* Configures the editor. Passed onto the <code>realEditor</code>.
*/
public Component getTreeCellEditorComponent(JTree tree, Object value,
boolean isSelected,
boolean expanded,
boolean leaf, int row) {
setTree(tree);
lastRow = row;
determineOffset(tree, value, isSelected, expanded, leaf, row);
if (editingComponent != null) {
editingContainer.remove(editingComponent);
}
editingComponent = realEditor.getTreeCellEditorComponent(tree, value,
isSelected, expanded,leaf, row);
// this is kept for backwards compatibility but isn't really needed
// with the current BasicTreeUI implementation.
TreePath newPath = tree.getPathForRow(row);
canEdit = (lastPath != null && newPath != null &&
lastPath.equals(newPath));
Font font = getFont();
if(font == null) {
if(renderer != null)
font = renderer.getFont();
if(font == null)
font = tree.getFont();
}
editingContainer.setFont(font);
prepareForEditing();
return editingContainer;
}
Returns the value currently being edited.
Returns: the value currently being edited
/**
* Returns the value currently being edited.
* @return the value currently being edited
*/
public Object getCellEditorValue() {
return realEditor.getCellEditorValue();
}
If the realEditor
returns true to this
message, prepareForEditing
is messaged and true is returned.
/**
* If the <code>realEditor</code> returns true to this
* message, <code>prepareForEditing</code>
* is messaged and true is returned.
*/
public boolean isCellEditable(EventObject event) {
boolean retValue = false;
boolean editable = false;
if (event != null) {
if (event.getSource() instanceof JTree) {
setTree((JTree)event.getSource());
if (event instanceof MouseEvent) {
TreePath path = tree.getPathForLocation(
((MouseEvent)event).getX(),
((MouseEvent)event).getY());
editable = (lastPath != null && path != null &&
lastPath.equals(path));
if (path!=null) {
lastRow = tree.getRowForPath(path);
Object value = path.getLastPathComponent();
boolean isSelected = tree.isRowSelected(lastRow);
boolean expanded = tree.isExpanded(path);
TreeModel treeModel = tree.getModel();
boolean leaf = treeModel.isLeaf(value);
determineOffset(tree, value, isSelected,
expanded, leaf, lastRow);
}
}
}
}
if(!realEditor.isCellEditable(event))
return false;
if(canEditImmediately(event))
retValue = true;
else if(editable && shouldStartEditingTimer(event)) {
startEditingTimer();
}
else if(timer != null && timer.isRunning())
timer.stop();
if(retValue)
prepareForEditing();
return retValue;
}
Messages the realEditor
for the return value.
/**
* Messages the <code>realEditor</code> for the return value.
*/
public boolean shouldSelectCell(EventObject event) {
return realEditor.shouldSelectCell(event);
}
If the realEditor
will allow editing to stop,
the realEditor
is removed and true is returned,
otherwise false is returned.
/**
* If the <code>realEditor</code> will allow editing to stop,
* the <code>realEditor</code> is removed and true is returned,
* otherwise false is returned.
*/
public boolean stopCellEditing() {
if(realEditor.stopCellEditing()) {
cleanupAfterEditing();
return true;
}
return false;
}
Messages cancelCellEditing
to the
realEditor
and removes it from this instance.
/**
* Messages <code>cancelCellEditing</code> to the
* <code>realEditor</code> and removes it from this instance.
*/
public void cancelCellEditing() {
realEditor.cancelCellEditing();
cleanupAfterEditing();
}
Adds the CellEditorListener
.
Params: - l – the listener to be added
/**
* Adds the <code>CellEditorListener</code>.
* @param l the listener to be added
*/
public void addCellEditorListener(CellEditorListener l) {
realEditor.addCellEditorListener(l);
}
Removes the previously added CellEditorListener
.
Params: - l – the listener to be removed
/**
* Removes the previously added <code>CellEditorListener</code>.
* @param l the listener to be removed
*/
public void removeCellEditorListener(CellEditorListener l) {
realEditor.removeCellEditorListener(l);
}
Returns an array of all the CellEditorListener
s added
to this DefaultTreeCellEditor with addCellEditorListener().
Returns: all of the CellEditorListener
s added or an empty
array if no listeners have been added Since: 1.4
/**
* Returns an array of all the <code>CellEditorListener</code>s added
* to this DefaultTreeCellEditor with addCellEditorListener().
*
* @return all of the <code>CellEditorListener</code>s added or an empty
* array if no listeners have been added
* @since 1.4
*/
public CellEditorListener[] getCellEditorListeners() {
return ((DefaultCellEditor)realEditor).getCellEditorListeners();
}
//
// TreeSelectionListener
//
Resets lastPath
.
/**
* Resets <code>lastPath</code>.
*/
public void valueChanged(TreeSelectionEvent e) {
if(tree != null) {
if(tree.getSelectionCount() == 1)
lastPath = tree.getSelectionPath();
else
lastPath = null;
}
if(timer != null) {
timer.stop();
}
}
//
// ActionListener (for Timer).
//
Messaged when the timer fires, this will start the editing
session.
/**
* Messaged when the timer fires, this will start the editing
* session.
*/
public void actionPerformed(ActionEvent e) {
if(tree != null && lastPath != null) {
tree.startEditingAtPath(lastPath);
}
}
//
// Local methods
//
Sets the tree currently editing for. This is needed to add
a selection listener.
Params: - newTree – the new tree to be edited
/**
* Sets the tree currently editing for. This is needed to add
* a selection listener.
* @param newTree the new tree to be edited
*/
protected void setTree(JTree newTree) {
if(tree != newTree) {
if(tree != null)
tree.removeTreeSelectionListener(this);
tree = newTree;
if(tree != null)
tree.addTreeSelectionListener(this);
if(timer != null) {
timer.stop();
}
}
}
Returns true if event
is a MouseEvent
and the click count is 1.
Params: - event – the event being studied
/**
* Returns true if <code>event</code> is a <code>MouseEvent</code>
* and the click count is 1.
* @param event the event being studied
*/
protected boolean shouldStartEditingTimer(EventObject event) {
if((event instanceof MouseEvent) &&
SwingUtilities.isLeftMouseButton((MouseEvent)event)) {
MouseEvent me = (MouseEvent)event;
return (me.getClickCount() == 1 &&
inHitRegion(me.getX(), me.getY()));
}
return false;
}
Starts the editing timer.
/**
* Starts the editing timer.
*/
protected void startEditingTimer() {
if(timer == null) {
timer = new Timer(1200, this);
timer.setRepeats(false);
}
timer.start();
}
Returns true if event
is null
,
or it is a MouseEvent
with a click count > 2
and inHitRegion
returns true.
Params: - event – the event being studied
/**
* Returns true if <code>event</code> is <code>null</code>,
* or it is a <code>MouseEvent</code> with a click count > 2
* and <code>inHitRegion</code> returns true.
* @param event the event being studied
*/
protected boolean canEditImmediately(EventObject event) {
if((event instanceof MouseEvent) &&
SwingUtilities.isLeftMouseButton((MouseEvent)event)) {
MouseEvent me = (MouseEvent)event;
return ((me.getClickCount() > 2) &&
inHitRegion(me.getX(), me.getY()));
}
return (event == null);
}
Returns true if the passed in location is a valid mouse location
to start editing from. This is implemented to return false if
x
is <= the width of the icon and icon gap displayed
by the renderer. In other words this returns true if the user
clicks over the text part displayed by the renderer, and false
otherwise.
Params: - x – the x-coordinate of the point
- y – the y-coordinate of the point
Returns: true if the passed in location is a valid mouse location
/**
* Returns true if the passed in location is a valid mouse location
* to start editing from. This is implemented to return false if
* <code>x</code> is <= the width of the icon and icon gap displayed
* by the renderer. In other words this returns true if the user
* clicks over the text part displayed by the renderer, and false
* otherwise.
* @param x the x-coordinate of the point
* @param y the y-coordinate of the point
* @return true if the passed in location is a valid mouse location
*/
protected boolean inHitRegion(int x, int y) {
if(lastRow != -1 && tree != null) {
Rectangle bounds = tree.getRowBounds(lastRow);
ComponentOrientation treeOrientation = tree.getComponentOrientation();
if ( treeOrientation.isLeftToRight() ) {
if (bounds != null && x <= (bounds.x + offset) &&
offset < (bounds.width - 5)) {
return false;
}
} else if ( bounds != null &&
( x >= (bounds.x+bounds.width-offset+5) ||
x <= (bounds.x + 5) ) &&
offset < (bounds.width - 5) ) {
return false;
}
}
return true;
}
protected void determineOffset(JTree tree, Object value,
boolean isSelected, boolean expanded,
boolean leaf, int row) {
if(renderer != null) {
if(leaf)
editingIcon = renderer.getLeafIcon();
else if(expanded)
editingIcon = renderer.getOpenIcon();
else
editingIcon = renderer.getClosedIcon();
if(editingIcon != null)
offset = renderer.getIconTextGap() +
editingIcon.getIconWidth();
else
offset = renderer.getIconTextGap();
}
else {
editingIcon = null;
offset = 0;
}
}
Invoked just before editing is to start. Will add the
editingComponent
to the
editingContainer
.
/**
* Invoked just before editing is to start. Will add the
* <code>editingComponent</code> to the
* <code>editingContainer</code>.
*/
protected void prepareForEditing() {
if (editingComponent != null) {
editingContainer.add(editingComponent);
}
}
Creates the container to manage placement of
editingComponent
.
/**
* Creates the container to manage placement of
* <code>editingComponent</code>.
*/
protected Container createContainer() {
return new EditorContainer();
}
This is invoked if a TreeCellEditor
is not supplied in the constructor.
It returns a TextField
editor.
Returns: a new TextField
editor
/**
* This is invoked if a <code>TreeCellEditor</code>
* is not supplied in the constructor.
* It returns a <code>TextField</code> editor.
* @return a new <code>TextField</code> editor
*/
protected TreeCellEditor createTreeCellEditor() {
Border aBorder = UIManager.getBorder("Tree.editorBorder");
DefaultCellEditor editor = new DefaultCellEditor
(new DefaultTextField(aBorder)) {
public boolean shouldSelectCell(EventObject event) {
boolean retValue = super.shouldSelectCell(event);
return retValue;
}
};
// One click to edit.
editor.setClickCountToStart(1);
return editor;
}
Cleans up any state after editing has completed. Removes the
editingComponent
the editingContainer
.
/**
* Cleans up any state after editing has completed. Removes the
* <code>editingComponent</code> the <code>editingContainer</code>.
*/
private void cleanupAfterEditing() {
if (editingComponent != null) {
editingContainer.remove(editingComponent);
}
editingComponent = null;
}
// Serialization support.
private void writeObject(ObjectOutputStream s) throws IOException {
Vector<Object> values = new Vector<Object>();
s.defaultWriteObject();
// Save the realEditor, if its Serializable.
if(realEditor != null && realEditor instanceof Serializable) {
values.addElement("realEditor");
values.addElement(realEditor);
}
s.writeObject(values);
}
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException {
s.defaultReadObject();
Vector values = (Vector)s.readObject();
int indexCounter = 0;
int maxCounter = values.size();
if(indexCounter < maxCounter && values.elementAt(indexCounter).
equals("realEditor")) {
realEditor = (TreeCellEditor)values.elementAt(++indexCounter);
indexCounter++;
}
}
TextField
used when no editor is supplied.
This textfield locks into the border it is constructed with.
It also prefers its parents font over its font. And if the
renderer is not null
and no font
has been specified the preferred height is that of the renderer.
/**
* <code>TextField</code> used when no editor is supplied.
* This textfield locks into the border it is constructed with.
* It also prefers its parents font over its font. And if the
* renderer is not <code>null</code> and no font
* has been specified the preferred height is that of the renderer.
*/
public class DefaultTextField extends JTextField {
Border to use. /** Border to use. */
protected Border border;
Constructs a
DefaultTreeCellEditor.DefaultTextField
object.
Params: - border – a
Border
object
Since: 1.4
/**
* Constructs a
* <code>DefaultTreeCellEditor.DefaultTextField</code> object.
*
* @param border a <code>Border</code> object
* @since 1.4
*/
public DefaultTextField(Border border) {
setBorder(border);
}
Sets the border of this component.
This is a bound property.
Params: - border – the border to be rendered for this component
See Also: @beaninfo
bound: true
preferred: true
attribute: visualUpdate true
description: The component's border.
/**
* Sets the border of this component.<p>
* This is a bound property.
*
* @param border the border to be rendered for this component
* @see Border
* @see CompoundBorder
* @beaninfo
* bound: true
* preferred: true
* attribute: visualUpdate true
* description: The component's border.
*/
public void setBorder(Border border) {
super.setBorder(border);
this.border = border;
}
Overrides JComponent.getBorder
to
returns the current border.
/**
* Overrides <code>JComponent.getBorder</code> to
* returns the current border.
*/
public Border getBorder() {
return border;
}
// implements java.awt.MenuContainer
public Font getFont() {
Font font = super.getFont();
// Prefer the parent containers font if our font is a
// FontUIResource
if(font instanceof FontUIResource) {
Container parent = getParent();
if(parent != null && parent.getFont() != null)
font = parent.getFont();
}
return font;
}
Overrides JTextField.getPreferredSize
to
return the preferred size based on current font, if set,
or else use renderer's font.
Returns: a Dimension
object containing
the preferred size
/**
* Overrides <code>JTextField.getPreferredSize</code> to
* return the preferred size based on current font, if set,
* or else use renderer's font.
* @return a <code>Dimension</code> object containing
* the preferred size
*/
public Dimension getPreferredSize() {
Dimension size = super.getPreferredSize();
// If not font has been set, prefer the renderers height.
if(renderer != null &&
DefaultTreeCellEditor.this.getFont() == null) {
Dimension rSize = renderer.getPreferredSize();
size.height = rSize.height;
}
return size;
}
}
Container responsible for placing the editingComponent
.
/**
* Container responsible for placing the <code>editingComponent</code>.
*/
public class EditorContainer extends Container {
Constructs an EditorContainer
object.
/**
* Constructs an <code>EditorContainer</code> object.
*/
public EditorContainer() {
setLayout(null);
}
// This should not be used. It will be removed when new API is
// allowed.
public void EditorContainer() {
setLayout(null);
}
Overrides Container.paint
to paint the node's
icon and use the selection color for the background.
/**
* Overrides <code>Container.paint</code> to paint the node's
* icon and use the selection color for the background.
*/
public void paint(Graphics g) {
int width = getWidth();
int height = getHeight();
// Then the icon.
if(editingIcon != null) {
int yLoc = calculateIconY(editingIcon);
if (getComponentOrientation().isLeftToRight()) {
editingIcon.paintIcon(this, g, 0, yLoc);
} else {
editingIcon.paintIcon(
this, g, width - editingIcon.getIconWidth(),
yLoc);
}
}
// Border selection color
Color background = getBorderSelectionColor();
if(background != null) {
g.setColor(background);
g.drawRect(0, 0, width - 1, height - 1);
}
super.paint(g);
}
Lays out this Container
. If editing,
the editor will be placed at
offset
in the x direction and 0 for y.
/**
* Lays out this <code>Container</code>. If editing,
* the editor will be placed at
* <code>offset</code> in the x direction and 0 for y.
*/
public void doLayout() {
if(editingComponent != null) {
int width = getWidth();
int height = getHeight();
if (getComponentOrientation().isLeftToRight()) {
editingComponent.setBounds(
offset, 0, width - offset, height);
} else {
editingComponent.setBounds(
0, 0, width - offset, height);
}
}
}
Calculate the y location for the icon.
/**
* Calculate the y location for the icon.
*/
private int calculateIconY(Icon icon) {
// To make sure the icon position matches that of the
// renderer, use the same algorithm as JLabel
// (SwingUtilities.layoutCompoundLabel).
int iconHeight = icon.getIconHeight();
int textHeight = editingComponent.getFontMetrics(
editingComponent.getFont()).getHeight();
int textY = iconHeight / 2 - textHeight / 2;
int totalY = Math.min(0, textY);
int totalHeight = Math.max(iconHeight, textY + textHeight) -
totalY;
return getHeight() / 2 - (totalY + (totalHeight / 2));
}
Returns the preferred size for the Container
.
This will be at least preferred size of the editor plus
offset
.
Returns: a Dimension
containing the preferred
size for the Container
; if
editingComponent
is null
the
Dimension
returned is 0, 0
/**
* Returns the preferred size for the <code>Container</code>.
* This will be at least preferred size of the editor plus
* <code>offset</code>.
* @return a <code>Dimension</code> containing the preferred
* size for the <code>Container</code>; if
* <code>editingComponent</code> is <code>null</code> the
* <code>Dimension</code> returned is 0, 0
*/
public Dimension getPreferredSize() {
if(editingComponent != null) {
Dimension pSize = editingComponent.getPreferredSize();
pSize.width += offset + 5;
Dimension rSize = (renderer != null) ?
renderer.getPreferredSize() : null;
if(rSize != null)
pSize.height = Math.max(pSize.height, rSize.height);
if(editingIcon != null)
pSize.height = Math.max(pSize.height,
editingIcon.getIconHeight());
// Make sure width is at least 100.
pSize.width = Math.max(pSize.width, 100);
return pSize;
}
return new Dimension(0, 0);
}
}
}