38 |
|
|
39 |
package javax.swing.plaf.metal; |
package javax.swing.plaf.metal; |
40 |
|
|
41 |
|
import java.awt.Graphics; |
42 |
|
import java.awt.Insets; |
43 |
|
import java.awt.Rectangle; |
44 |
|
import java.awt.event.ComponentListener; |
45 |
|
import java.awt.event.FocusListener; |
46 |
|
import java.awt.event.KeyListener; |
47 |
|
import java.beans.PropertyChangeListener; |
48 |
import java.util.HashMap; |
import java.util.HashMap; |
49 |
|
import java.util.Hashtable; |
50 |
|
|
51 |
import javax.swing.JComponent; |
import javax.swing.JComponent; |
52 |
|
import javax.swing.JTree; |
53 |
|
import javax.swing.UIDefaults; |
54 |
|
import javax.swing.UIManager; |
55 |
|
import javax.swing.tree.TreeCellEditor; |
56 |
|
import javax.swing.tree.TreeModel; |
57 |
|
import javax.swing.tree.TreePath; |
58 |
|
import javax.swing.event.CellEditorListener; |
59 |
|
import javax.swing.event.MouseInputListener; |
60 |
|
import javax.swing.event.TreeExpansionListener; |
61 |
|
import javax.swing.event.TreeModelListener; |
62 |
|
import javax.swing.event.TreeSelectionListener; |
63 |
|
|
64 |
import javax.swing.plaf.ComponentUI; |
import javax.swing.plaf.ComponentUI; |
65 |
import javax.swing.plaf.basic.BasicTreeUI; |
import javax.swing.plaf.basic.BasicTreeUI; |
66 |
|
|
68 |
extends BasicTreeUI |
extends BasicTreeUI |
69 |
{ |
{ |
70 |
|
|
71 |
|
/** Listeners */ |
72 |
|
private PropertyChangeListener propertyChangeListener; |
73 |
|
private FocusListener focusListener; |
74 |
|
private TreeSelectionListener treeSelectionListener; |
75 |
|
private MouseInputListener mouseInputListener; |
76 |
|
private KeyListener keyListener; |
77 |
|
private PropertyChangeListener selectionModelPropertyChangeListener; |
78 |
|
private ComponentListener componentListener; |
79 |
|
private CellEditorListener cellEditorListener; |
80 |
|
private TreeExpansionListener treeExpansionListener; |
81 |
|
private TreeModelListener treeModelListener; |
82 |
|
|
83 |
/** The UI instances for MetalTreeUIs */ |
/** The UI instances for MetalTreeUIs */ |
84 |
private static HashMap instances = null; |
private static HashMap instances = null; |
85 |
|
|
115 |
|
|
116 |
return instance; |
return instance; |
117 |
} |
} |
118 |
|
|
119 |
|
/** |
120 |
|
* The horizontal element of legs between nodes starts at the right of the |
121 |
|
* left-hand side of the child node by default. This method makes the |
122 |
|
* leg end before that. |
123 |
|
*/ |
124 |
|
protected int getHorizontalLegBuffer() |
125 |
|
{ |
126 |
|
return super.getHorizontalLegBuffer(); |
127 |
|
} |
128 |
|
|
129 |
|
/** |
130 |
|
* Configures the specified component appropriate for the look and feel. |
131 |
|
* This method is invoked when the ComponentUI instance is being installed |
132 |
|
* as the UI delegate on the specified component. This method should completely |
133 |
|
* configure the component for the look and feel, including the following: |
134 |
|
* 1. Install any default property values for color, fonts, borders, icons, |
135 |
|
* opacity, etc. on the component. Whenever possible, property values |
136 |
|
* initialized by the client program should not be overridden. |
137 |
|
* 2. Install a LayoutManager on the component if necessary. |
138 |
|
* 3. Create/add any required sub-components to the component. |
139 |
|
* 4. Create/install event listeners on the component. |
140 |
|
* 5. Create/install a PropertyChangeListener on the component in order |
141 |
|
* to detect and respond to component property changes appropriately. |
142 |
|
* 6. Install keyboard UI (mnemonics, traversal, etc.) on the component. |
143 |
|
* 7. Initialize any appropriate instance data. |
144 |
|
*/ |
145 |
|
public void installUI(JComponent c) |
146 |
|
{ |
147 |
|
tree = (JTree) c; |
148 |
|
configureLayoutCache(); |
149 |
|
|
150 |
|
UIDefaults defaults = UIManager.getLookAndFeelDefaults(); |
151 |
|
tree.setFont(defaults.getFont("Tree.font")); |
152 |
|
tree.setForeground(defaults.getColor("Tree.foreground")); |
153 |
|
tree.setBackground(defaults.getColor("Tree.background")); |
154 |
|
tree.setOpaque(true); |
155 |
|
tree.setScrollsOnExpand(defaults.getBoolean("Tree.scrollsOnExpand")); |
156 |
|
rightChildIndent = defaults.getInt("Tree.rightChildIndent"); |
157 |
|
leftChildIndent = defaults.getInt("Tree.leftChildIndent"); |
158 |
|
setRowHeight(defaults.getInt("Tree.rowHeight")); |
159 |
|
tree.requestFocusInWindow(false); |
160 |
|
|
161 |
|
setExpandedIcon(defaults.getIcon("Tree.expandedIcon")); |
162 |
|
setCollapsedIcon(defaults.getIcon("Tree.collapsedIcon")); |
163 |
|
|
164 |
|
currentCellRenderer = createDefaultCellRenderer(); |
165 |
|
rendererPane = createCellRendererPane(); |
166 |
|
createdRenderer = true; |
167 |
|
setCellEditor(createDefaultCellEditor()); |
168 |
|
createdCellEditor = true; |
169 |
|
TreeModel mod = tree.getModel(); |
170 |
|
setModel(mod); |
171 |
|
tree.setRootVisible(true); |
172 |
|
if (mod != null) |
173 |
|
tree.expandPath(new TreePath(mod.getRoot())); |
174 |
|
treeSelectionModel = tree.getSelectionModel(); |
175 |
|
drawingCache = new Hashtable(); |
176 |
|
nodeDimensions = createNodeDimensions(); |
177 |
|
|
178 |
|
propertyChangeListener = createPropertyChangeListener(); |
179 |
|
focusListener = createFocusListener(); |
180 |
|
treeSelectionListener = createTreeSelectionListener(); |
181 |
|
mouseInputListener = new MouseInputHandler(null, null, null); |
182 |
|
keyListener = createKeyListener(); |
183 |
|
selectionModelPropertyChangeListener = createSelectionModelPropertyChangeListener(); |
184 |
|
componentListener = createComponentListener(); |
185 |
|
cellEditorListener = createCellEditorListener(); |
186 |
|
treeExpansionListener = createTreeExpansionListener(); |
187 |
|
treeModelListener = createTreeModelListener(); |
188 |
|
|
189 |
|
editingRow = -1; |
190 |
|
lastSelectedRow = -1; |
191 |
|
|
192 |
|
installKeyboardActions(); |
193 |
|
|
194 |
|
tree.addPropertyChangeListener(propertyChangeListener); |
195 |
|
tree.addFocusListener(focusListener); |
196 |
|
tree.addTreeSelectionListener(treeSelectionListener); |
197 |
|
tree.addMouseListener(mouseInputListener); |
198 |
|
tree.addKeyListener(keyListener); |
199 |
|
tree.addPropertyChangeListener(selectionModelPropertyChangeListener); |
200 |
|
tree.addComponentListener(componentListener); |
201 |
|
tree.addTreeExpansionListener(treeExpansionListener); |
202 |
|
if (treeModel != null) |
203 |
|
treeModel.addTreeModelListener(treeModelListener); |
204 |
|
|
205 |
|
completeUIInstall(); |
206 |
|
} |
207 |
|
|
208 |
|
/** |
209 |
|
* Reverses configuration which was done on the specified component during |
210 |
|
* installUI. This method is invoked when this UIComponent instance is being |
211 |
|
* removed as the UI delegate for the specified component. This method should |
212 |
|
* undo the configuration performed in installUI, being careful to leave the |
213 |
|
* JComponent instance in a clean state (no extraneous listeners, |
214 |
|
* look-and-feel-specific property objects, etc.). This should include |
215 |
|
* the following: |
216 |
|
* 1. Remove any UI-set borders from the component. |
217 |
|
* 2. Remove any UI-set layout managers on the component. |
218 |
|
* 3. Remove any UI-added sub-components from the component. |
219 |
|
* 4. Remove any UI-added event/property listeners from the component. |
220 |
|
* 5. Remove any UI-installed keyboard UI from the component. |
221 |
|
* 6. Nullify any allocated instance data objects to allow for GC. |
222 |
|
*/ |
223 |
|
public void uninstallUI(JComponent c) |
224 |
|
{ |
225 |
|
tree.setFont(null); |
226 |
|
tree.setForeground(null); |
227 |
|
tree.setBackground(null); |
228 |
|
|
229 |
|
uninstallKeyboardActions(); |
230 |
|
|
231 |
|
tree.removePropertyChangeListener(propertyChangeListener); |
232 |
|
tree.removeFocusListener(focusListener); |
233 |
|
tree.removeTreeSelectionListener(treeSelectionListener); |
234 |
|
tree.removeMouseListener(mouseInputListener); |
235 |
|
tree.removeKeyListener(keyListener); |
236 |
|
tree.removePropertyChangeListener(selectionModelPropertyChangeListener); |
237 |
|
tree.removeComponentListener(componentListener); |
238 |
|
tree.removeTreeExpansionListener(treeExpansionListener); |
239 |
|
|
240 |
|
TreeCellEditor tce = tree.getCellEditor(); |
241 |
|
if (tce != null) |
242 |
|
tce.removeCellEditorListener(cellEditorListener); |
243 |
|
TreeModel tm = tree.getModel(); |
244 |
|
if (tm != null) |
245 |
|
tm.removeTreeModelListener(treeModelListener); |
246 |
|
|
247 |
|
tree = null; |
248 |
|
uninstallComponents(); |
249 |
|
completeUIUninstall(); |
250 |
|
} |
251 |
|
|
252 |
|
/** |
253 |
|
* This function converts between the string passed into the client |
254 |
|
* property and the internal representation (currently an int). |
255 |
|
* |
256 |
|
* @param lineStyleFlag - String representation |
257 |
|
*/ |
258 |
|
protected void decodeLineStyle(Object lineStyleFlag) |
259 |
|
{ |
260 |
|
// FIXME: not implemented |
261 |
|
} |
262 |
|
|
263 |
|
/** |
264 |
|
* Checks if the location is in expand control. |
265 |
|
* |
266 |
|
* @param row - current row |
267 |
|
* @param rowLevel - current level |
268 |
|
* @param mouseX - current x location of the mouse click |
269 |
|
* @param mouseY - current y location of the mouse click |
270 |
|
*/ |
271 |
|
protected boolean isLocationInExpandControl(int row, int rowLevel, |
272 |
|
int mouseX, int mouseY) |
273 |
|
{ |
274 |
|
return super.isLocationInExpandControl(tree.getPathForRow(row), |
275 |
|
mouseX, mouseY); |
276 |
|
} |
277 |
|
|
278 |
|
/** |
279 |
|
* Paints the specified component appropriate for the look and feel. |
280 |
|
* This method is invoked from the ComponentUI.update method when the |
281 |
|
* specified component is being painted. Subclasses should override this |
282 |
|
* method and use the specified Graphics object to render the content of |
283 |
|
* the component. |
284 |
|
* |
285 |
|
* @param g - the current graphics configuration. |
286 |
|
* @param c - the current component to draw |
287 |
|
*/ |
288 |
|
public void paint(Graphics g, JComponent c) |
289 |
|
{ |
290 |
|
// Calls BasicTreeUI's paint since it takes care of painting all |
291 |
|
// types of icons. |
292 |
|
super.paint(g, c); |
293 |
|
} |
294 |
|
|
295 |
|
/** |
296 |
|
* Paints the horizontal separators. |
297 |
|
* |
298 |
|
* @param g - the current graphics configuration. |
299 |
|
* @param c - the current component to draw |
300 |
|
*/ |
301 |
|
protected void paintHorizontalSeparators(Graphics g, JComponent c) |
302 |
|
{ |
303 |
|
// FIXME: not implemented |
304 |
|
} |
305 |
|
|
306 |
|
|
307 |
|
/** |
308 |
|
* Paints the vertical part of the leg. The receiver should NOT modify |
309 |
|
* clipBounds, insets. |
310 |
|
* |
311 |
|
* @param g - the current graphics configuration. |
312 |
|
* @param clipBounds - |
313 |
|
* @param insets - |
314 |
|
* @param path - the current path |
315 |
|
*/ |
316 |
|
protected void paintVerticalPartOfLeg(Graphics g, Rectangle clipBounds, |
317 |
|
Insets insets, TreePath path) |
318 |
|
{ |
319 |
|
super.paintVerticalPartOfLeg(g, clipBounds, insets, path); |
320 |
|
} |
321 |
|
|
322 |
|
/** |
323 |
|
* Paints the horizontal part of the leg. The receiver should NOT \ |
324 |
|
* modify clipBounds, or insets. |
325 |
|
* NOTE: parentRow can be -1 if the root is not visible. |
326 |
|
*/ |
327 |
|
protected void paintHorizontalPartOfLeg(Graphics g, Rectangle clipBounds, |
328 |
|
Insets insets, Rectangle bounds, |
329 |
|
TreePath path, int row, |
330 |
|
boolean isExpanded, boolean hasBeenExpanded, |
331 |
|
boolean isLeaf) |
332 |
|
{ |
333 |
|
super.paintHorizontalPartOfLeg(g, clipBounds, insets, bounds, path, row, |
334 |
|
isExpanded, hasBeenExpanded, isLeaf); |
335 |
|
} |
336 |
} |
} |