001 /*
002 * $Id: DefaultXTreeCellEditor.java,v 1.3 2006/01/12 15:15:56 kleopatra Exp $
003 *
004 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
005 * Santa Clara, California 95054, U.S.A. All rights reserved.
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * You should have received a copy of the GNU Lesser General Public
018 * License along with this library; if not, write to the Free Software
019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
020 */
021 package org.jdesktop.swingx.tree;
022
023 import java.awt.ComponentOrientation;
024 import java.awt.Container;
025 import java.awt.Dimension;
026 import java.awt.Graphics;
027
028 import javax.swing.Icon;
029 import javax.swing.JTree;
030 import javax.swing.tree.DefaultTreeCellEditor;
031 import javax.swing.tree.DefaultTreeCellRenderer;
032 import javax.swing.tree.TreeCellEditor;
033
034 /**
035 * Subclassed to hack around core bug with RtoL editing (#4980473).
036 *
037 * The price to pay is currently is to guarantee a minimum size of the
038 * editing field (is only one char wide if the node value is null).
039 *
040 * PENDING: any possibility to position the editorContainer?
041 * BasicTreeUI adds it to the tree and positions at the node location.
042 * That's not a problem in LToR, only
043 * in RToL
044 *
045 *
046 * @author Jeanette Winzenburg
047 */
048 public class DefaultXTreeCellEditor extends DefaultTreeCellEditor {
049
050 public DefaultXTreeCellEditor(JTree tree, DefaultTreeCellRenderer renderer) {
051 super(tree, renderer);
052 }
053
054 public DefaultXTreeCellEditor(JTree tree, DefaultTreeCellRenderer renderer,
055 TreeCellEditor editor) {
056 super(tree, renderer, editor);
057 }
058
059 public void setRenderer(DefaultTreeCellRenderer renderer) {
060 this.renderer = renderer;
061 }
062
063 public class XEditorContainer extends EditorContainer {
064
065 @Override
066 public Dimension getPreferredSize() {
067 if (isRightToLeft()) {
068 if(editingComponent != null) {
069 Dimension pSize = editingComponent.getPreferredSize();
070
071 pSize.width += offset + 5;
072
073 Dimension rSize = (renderer != null) ?
074 renderer.getPreferredSize() : null;
075
076 if(rSize != null)
077 pSize.height = Math.max(pSize.height, rSize.height);
078 if(editingIcon != null)
079 pSize.height = Math.max(pSize.height,
080 editingIcon.getIconHeight());
081
082 // trying to enforce a minimum size leads to field being painted over the icon
083 // Make sure width is at least 100.
084 // pSize.width = Math.max(pSize.width, 100);
085 return pSize;
086 }
087 return new Dimension(0, 0);
088 }
089 return super.getPreferredSize();
090
091 }
092
093 @Override
094 public void doLayout() {
095 if (isRightToLeft()) {
096 Dimension cSize = getSize();
097
098 editingComponent.getPreferredSize();
099 editingComponent.setLocation(0, 0);
100 editingComponent.setBounds(0, 0,
101 cSize.width - offset,
102 cSize.height);
103 } else {
104
105 super.doLayout();
106 }
107 }
108
109
110 @Override
111 public void paint(Graphics g) {
112 if (isRightToLeft()) {
113 Dimension size = getSize();
114
115 // Then the icon.
116 if (editingIcon != null) {
117 int yLoc = Math.max(0, (size.height - editingIcon
118 .getIconHeight()) / 2);
119 int xLoc = Math.max(0, size.width - offset);
120 editingIcon.paintIcon(this, g, xLoc, yLoc);
121 }
122 // need to prevent super from painting the icon
123 Icon rememberIcon = editingIcon;
124 editingIcon = null;
125 super.paint(g);
126 editingIcon = rememberIcon;
127
128 } else {
129 super.paint(g);
130 }
131 }
132
133 }
134
135
136 @Override
137 protected Container createContainer() {
138 return new XEditorContainer();
139 }
140
141 @Override
142 protected void prepareForEditing() {
143 super.prepareForEditing();
144 applyComponentOrientation();
145 }
146
147 protected void applyComponentOrientation() {
148 if (tree != null) {
149 editingContainer.applyComponentOrientation(tree.getComponentOrientation());
150 }
151
152 }
153
154 /**
155 * @return
156 */
157 private boolean isRightToLeft() {
158 return (tree != null) && (!tree.getComponentOrientation().isLeftToRight());
159 }
160
161 }