001 /*
002 * $Id: DefaultXTreeCellEditor.java 3310 2009-03-26 10:25:24Z kleopatra $
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.Container;
024 import java.awt.Dimension;
025 import java.awt.Graphics;
026
027 import javax.swing.Icon;
028 import javax.swing.JComponent;
029 import javax.swing.JTree;
030 import javax.swing.SwingUtilities;
031 import javax.swing.tree.DefaultTreeCellEditor;
032 import javax.swing.tree.DefaultTreeCellRenderer;
033 import javax.swing.tree.TreeCellEditor;
034
035 import org.jdesktop.swingx.decorator.UIDependent;
036
037 /**
038 * Subclassed to hack around core bug with RtoL editing (#4980473).
039 *
040 * The price to pay is currently is to guarantee a minimum size of the
041 * editing field (is only one char wide if the node value is null).
042 *
043 * PENDING: any possibility to position the editorContainer?
044 * BasicTreeUI adds it to the tree and positions at the node location.
045 * That's not a problem in LToR, only
046 * in RToL
047 *
048 *
049 * @author Jeanette Winzenburg
050 */
051 public class DefaultXTreeCellEditor extends DefaultTreeCellEditor implements UIDependent {
052
053 public DefaultXTreeCellEditor(JTree tree, DefaultTreeCellRenderer renderer) {
054 super(tree, renderer);
055 }
056
057 public DefaultXTreeCellEditor(JTree tree, DefaultTreeCellRenderer renderer,
058 TreeCellEditor editor) {
059 super(tree, renderer, editor);
060 }
061
062 public void setRenderer(DefaultTreeCellRenderer renderer) {
063 this.renderer = renderer;
064 }
065
066 public DefaultTreeCellRenderer getRenderer() {
067 return renderer;
068 }
069
070 public class XEditorContainer extends EditorContainer {
071
072 @Override
073 public Dimension getPreferredSize() {
074 if (isRightToLeft()) {
075 if(editingComponent != null) {
076 Dimension pSize = editingComponent.getPreferredSize();
077
078 pSize.width += offset + 5;
079
080 Dimension rSize = (renderer != null) ?
081 renderer.getPreferredSize() : null;
082
083 if(rSize != null)
084 pSize.height = Math.max(pSize.height, rSize.height);
085 if(editingIcon != null)
086 pSize.height = Math.max(pSize.height,
087 editingIcon.getIconHeight());
088
089 // trying to enforce a minimum size leads to field being painted over the icon
090 // Make sure width is at least 100.
091 // pSize.width = Math.max(pSize.width, 100);
092 return pSize;
093 }
094 return new Dimension(0, 0);
095 }
096 return super.getPreferredSize();
097
098 }
099
100 @Override
101 public void doLayout() {
102 if (isRightToLeft()) {
103 Dimension cSize = getSize();
104
105 editingComponent.getPreferredSize();
106 editingComponent.setLocation(0, 0);
107 editingComponent.setBounds(0, 0,
108 cSize.width - offset,
109 cSize.height);
110 } else {
111
112 super.doLayout();
113 }
114 }
115
116
117 @Override
118 public void paint(Graphics g) {
119 if (isRightToLeft()) {
120 Dimension size = getSize();
121
122 // Then the icon.
123 if (editingIcon != null) {
124 int yLoc = Math.max(0, (size.height - editingIcon
125 .getIconHeight()) / 2);
126 int xLoc = Math.max(0, size.width - offset);
127 editingIcon.paintIcon(this, g, xLoc, yLoc);
128 }
129 // need to prevent super from painting the icon
130 Icon rememberIcon = editingIcon;
131 editingIcon = null;
132 super.paint(g);
133 editingIcon = rememberIcon;
134
135 } else {
136 super.paint(g);
137 }
138 }
139
140 }
141
142
143 @Override
144 protected Container createContainer() {
145 return new XEditorContainer();
146 }
147
148 @Override
149 protected void prepareForEditing() {
150 super.prepareForEditing();
151 applyComponentOrientation();
152 }
153
154 protected void applyComponentOrientation() {
155 if (tree != null) {
156 editingContainer.applyComponentOrientation(tree.getComponentOrientation());
157 }
158
159 }
160
161 /**
162 * @return
163 */
164 private boolean isRightToLeft() {
165 return (tree != null) && (!tree.getComponentOrientation().isLeftToRight());
166 }
167
168 /**
169 * Implement UIDependent. Quick hack for #1060-swingx: icons lost on laf toggle.
170 */
171 public void updateUI() {
172 if (getRenderer() != null) {
173 SwingUtilities.updateComponentTreeUI(getRenderer());
174 }
175 if (realEditor instanceof JComponent) {
176 SwingUtilities.updateComponentTreeUI((JComponent) realEditor);
177 } else if (realEditor instanceof UIDependent) {
178 ((UIDependent) realEditor).updateUI();
179 }
180
181 }
182
183 }