123 |
*/ |
*/ |
124 |
public void paint(Graphics g) |
public void paint(Graphics g) |
125 |
{ |
{ |
|
lastPath = tree.getSelectionPath(); |
|
126 |
Rectangle tr = tree.getPathBounds(lastPath); |
Rectangle tr = tree.getPathBounds(lastPath); |
|
|
|
127 |
if (tr != null) |
if (tr != null) |
128 |
{ |
{ |
129 |
Insets i = ((DefaultTextField) editingComponent).getBorder() |
Insets i = ((DefaultTextField) editingComponent).getBorder() |
130 |
.getBorderInsets(this); |
.getBorderInsets(this); |
131 |
int textIconGap = 3; |
int textIconGap = 3; |
|
tr.height -= i.top; |
|
132 |
tr.x -= i.left; |
tr.x -= i.left; |
133 |
|
|
134 |
// paints icon |
// paints icon |
|
if (editingIcon == null) |
|
|
editingIcon = renderer.getIcon(); |
|
135 |
if (editingIcon != null) |
if (editingIcon != null) |
136 |
{ |
{ |
137 |
editingIcon.paintIcon(this, g, tr.x - editingIcon. |
editingIcon.paintIcon(this, g, tr.x - editingIcon. |
302 |
* Font to paint with, null indicates font of renderer is to be used. |
* Font to paint with, null indicates font of renderer is to be used. |
303 |
*/ |
*/ |
304 |
protected Font font; |
protected Font font; |
305 |
|
|
306 |
|
/** |
307 |
|
* Helper field used to save the last path seen while the timer was |
308 |
|
* running. |
309 |
|
*/ |
310 |
|
private TreePath tPath; |
311 |
|
|
312 |
/** |
/** |
313 |
* Constructs a DefaultTreeCellEditor object for a JTree using the |
* Constructs a DefaultTreeCellEditor object for a JTree using the |
340 |
if (editor == null) |
if (editor == null) |
341 |
editor = createTreeCellEditor(); |
editor = createTreeCellEditor(); |
342 |
realEditor = editor; |
realEditor = editor; |
343 |
|
|
344 |
|
tree.addTreeSelectionListener(this); |
345 |
editingContainer = createContainer(); |
editingContainer = createContainer(); |
346 |
UIDefaults defaults = UIManager.getLookAndFeelDefaults(); |
UIDefaults defaults = UIManager.getLookAndFeelDefaults(); |
347 |
setFont(defaults.getFont("Tree.font")); |
setFont(defaults.getFont("Tree.font")); |
361 |
DefaultTreeCellRenderer renderer, |
DefaultTreeCellRenderer renderer, |
362 |
TreeCellEditor editor) |
TreeCellEditor editor) |
363 |
{ |
{ |
364 |
if (tree != null) |
if (tree != null && lastPath != null) |
365 |
{ |
{ |
366 |
lastPath = tree.getSelectionPath(); |
Object val = lastPath.getLastPathComponent(); |
367 |
if (lastPath != null) |
boolean isLeaf = tree.getModel().isLeaf(val); |
368 |
{ |
boolean expanded = tree.isExpanded(lastPath); |
369 |
lastRow = tree.getRowForPath(lastPath); |
determineOffset(tree, val, true, expanded, isLeaf, lastRow); |
370 |
Object val = lastPath.getLastPathComponent(); |
|
371 |
boolean isLeaf = tree.getModel().isLeaf(val); |
// set up icon |
372 |
boolean expanded = tree.isExpanded(lastPath); |
if (isLeaf) |
373 |
determineOffset(tree, val, true, expanded, isLeaf, lastRow); |
renderer.setIcon(renderer.getLeafIcon()); |
374 |
|
else if (expanded) |
375 |
// set up icon |
renderer.setIcon(renderer.getOpenIcon()); |
376 |
if (isLeaf) |
else |
377 |
renderer.setIcon(renderer.getLeafIcon()); |
renderer.setIcon(renderer.getClosedIcon()); |
378 |
else if (expanded) |
editingIcon = renderer.getIcon(); |
379 |
renderer.setIcon(renderer.getOpenIcon()); |
|
380 |
else |
editingComponent = getTreeCellEditorComponent(tree, val, true, |
381 |
renderer.setIcon(renderer.getClosedIcon()); |
expanded, isLeaf, lastRow); |
|
|
|
|
editingIcon = renderer.getIcon(); |
|
|
|
|
|
editingComponent = getTreeCellEditorComponent(tree, val, |
|
|
true, |
|
|
expanded, |
|
|
isLeaf, |
|
|
lastRow); |
|
|
} |
|
382 |
} |
} |
383 |
} |
} |
384 |
|
|
385 |
/** |
/** |
386 |
* writeObject |
* writeObject |
387 |
* @param value0 TODO |
* |
388 |
* @exception IOException TODO |
* @param value0 |
389 |
|
* TODO |
390 |
|
* @exception IOException |
391 |
|
* TODO |
392 |
*/ |
*/ |
393 |
private void writeObject(ObjectOutputStream value0) throws IOException |
private void writeObject(ObjectOutputStream value0) throws IOException |
394 |
{ |
{ |
499 |
* @return true if editing can be started |
* @return true if editing can be started |
500 |
*/ |
*/ |
501 |
public boolean isCellEditable(EventObject event) |
public boolean isCellEditable(EventObject event) |
502 |
{ |
{ |
503 |
// FIXME: add canedit and caneditimmediately to if. |
if (editingComponent != null && realEditor.isCellEditable(event)) |
|
|
|
|
if (editingComponent == null) |
|
|
configureEditingComponent(tree, renderer, realEditor); |
|
|
|
|
|
if (realEditor.isCellEditable(event)) |
|
504 |
{ |
{ |
505 |
prepareForEditing(); |
prepareForEditing(); |
506 |
return true; |
return true; |
507 |
} |
} |
508 |
|
|
509 |
|
// Cell may not be currently editable, but may need to start timer. |
510 |
|
if (shouldStartEditingTimer(event)) |
511 |
|
startEditingTimer(); |
512 |
|
|
513 |
return false; |
return false; |
514 |
} |
} |
515 |
|
|
532 |
* @return true if editing was stopped; false otherwise |
* @return true if editing was stopped; false otherwise |
533 |
*/ |
*/ |
534 |
public boolean stopCellEditing() |
public boolean stopCellEditing() |
535 |
{ |
{ |
536 |
if (editingComponent == null) |
if (editingComponent != null && realEditor.stopCellEditing()) |
|
configureEditingComponent(tree, renderer, realEditor); |
|
|
|
|
|
if (realEditor.stopCellEditing()) |
|
537 |
{ |
{ |
538 |
timer.stop(); |
timer.stop(); |
539 |
tree.setCellEditor(null); |
tree.setCellEditor(null); |
547 |
* from this instance. |
* from this instance. |
548 |
*/ |
*/ |
549 |
public void cancelCellEditing() |
public void cancelCellEditing() |
550 |
{ |
{ |
551 |
if (editingComponent == null) |
if (editingComponent != null) |
552 |
configureEditingComponent(tree, renderer, realEditor); |
{ |
553 |
|
timer.stop(); |
554 |
timer.stop(); |
realEditor.cancelCellEditing(); |
555 |
realEditor.cancelCellEditing(); |
tree.setCellEditor(null); |
556 |
tree.setCellEditor(null); |
} |
557 |
} |
} |
558 |
|
|
559 |
/** |
/** |
597 |
{ |
{ |
598 |
lastPath = e.getNewLeadSelectionPath(); |
lastPath = e.getNewLeadSelectionPath(); |
599 |
lastRow = tree.getRowForPath(lastPath); |
lastRow = tree.getRowForPath(lastPath); |
600 |
TreeSelectionListener[] listeners = tree.getTreeSelectionListeners(); |
|
601 |
|
configureEditingComponent(tree, renderer, realEditor); |
|
for (int index = 0; index < listeners.length; ++index) |
|
|
listeners[index].valueChanged(e); |
|
602 |
} |
} |
603 |
|
|
604 |
/** |
/** |
605 |
* Messaged when the timer fires, this will start the editing session. |
* Messaged when the timer fires, this will start the editing session. |
606 |
* |
* |
608 |
*/ |
*/ |
609 |
public void actionPerformed(ActionEvent e) |
public void actionPerformed(ActionEvent e) |
610 |
{ |
{ |
611 |
if (tree != null && lastPath != null) |
lastPath = tree.getSelectionPath(); |
612 |
|
|
613 |
|
if (lastPath != null && tPath != null && tPath.equals(lastPath)) |
614 |
|
{ |
615 |
tree.startEditingAtPath(lastPath); |
tree.startEditingAtPath(lastPath); |
616 |
|
tPath = null; |
617 |
|
} |
618 |
|
else if (tPath == null) |
619 |
|
tPath = lastPath; |
620 |
|
else |
621 |
|
tPath = null; |
622 |
} |
} |
623 |
|
|
624 |
/** |
/** |
625 |
* Sets the tree currently editing for. This is needed to add a |
* Sets the tree currently editing for. This is needed to add a selection |
626 |
* selection listener. |
* listener. |
627 |
* |
* |
628 |
* @param newTree - the new tree to be edited |
* @param newTree - |
629 |
|
* the new tree to be edited |
630 |
*/ |
*/ |
631 |
protected void setTree(JTree newTree) |
protected void setTree(JTree newTree) |
632 |
{ |
{ |
641 |
*/ |
*/ |
642 |
protected boolean shouldStartEditingTimer(EventObject event) |
protected boolean shouldStartEditingTimer(EventObject event) |
643 |
{ |
{ |
644 |
if (!(event instanceof MouseEvent) && |
if ((event instanceof MouseEvent) && |
645 |
inHitRegion(((MouseEvent) event).getX(), |
((MouseEvent) event).getClickCount() == 1) |
|
((MouseEvent) event).getY()) && ((MouseEvent) event). |
|
|
getClickCount() == 1) |
|
646 |
return true; |
return true; |
647 |
return false; |
return false; |
648 |
} |
} |
667 |
*/ |
*/ |
668 |
protected boolean canEditImmediately(EventObject event) |
protected boolean canEditImmediately(EventObject event) |
669 |
{ |
{ |
670 |
if (event == null || (!(event instanceof MouseEvent) && (((MouseEvent) event). |
if (event == null || !(event instanceof MouseEvent) || (((MouseEvent) event). |
671 |
getClickCount() > 2 || inHitRegion(((MouseEvent) event).getX(), |
getClickCount() > 2 && inHitRegion(((MouseEvent) event).getX(), |
672 |
((MouseEvent) event).getY())))) |
((MouseEvent) event).getY()))) |
673 |
return true; |
return true; |
|
else if (shouldStartEditingTimer(event)) |
|
|
startEditingTimer(); |
|
674 |
return false; |
return false; |
675 |
} |
} |
676 |
|
|
689 |
*/ |
*/ |
690 |
protected boolean inHitRegion(int x, int y) |
protected boolean inHitRegion(int x, int y) |
691 |
{ |
{ |
692 |
Dimension d = editingContainer.getPreferredSize(); |
Rectangle bounds = tree.getPathBounds(lastPath); |
|
int textX = offset; |
|
|
|
|
|
if (editingIcon != null) |
|
|
textX += editingIcon.getIconWidth() + 4; |
|
693 |
|
|
694 |
if ((d.width > textX && x >= textX && x <= d.width) |
return bounds.contains(x, y); |
|
&& (y >= 0 && y <= d.height)) |
|
|
return true; |
|
|
return false; |
|
695 |
} |
} |
696 |
|
|
697 |
/** |
/** |
745 |
UIDefaults defaults = UIManager.getLookAndFeelDefaults(); |
UIDefaults defaults = UIManager.getLookAndFeelDefaults(); |
746 |
realEditor = new DefaultCellEditor(new DefaultTreeCellEditor.DefaultTextField( |
realEditor = new DefaultCellEditor(new DefaultTreeCellEditor.DefaultTextField( |
747 |
defaults.getBorder("Tree.selectionBorder"))); |
defaults.getBorder("Tree.selectionBorder"))); |
|
canEdit = true; |
|
748 |
return realEditor; |
return realEditor; |
749 |
} |
} |
750 |
} |
} |