Classifying Newsgroup Questions for JButton and JTree

Daqing Hou Eunice Yin and H. James Hoover

This report documents the classification of two samples of newsgroup questions for JTree and JButton. Eunice Yin and Daqing Hou collected and analyzed the JTree questions. Yin attempted a few classifications according to criteria such as the number of classes involved in each question, meta-patterns, and typical stories. Recently, Daqing Hou classified the questions according idetentified features of JTree. Daqing Hou also did a similar classification of JButton questions to understand inheritance related questions and programmer practice issues.

This report is divided into two sections: section 1 presents the classification results; rows marked with stars have been merged to other rows. Section 2 is the details of questions. Section 2 merged several intermediate results of Eunice's work, which is referenced using different notations in section 1 (sxxx for question number xxx in the first doc and ssxxx for question number xxx in the second doc; and xxx for question number xxx in the final list).

-Daqing Hou 2004-01-17

Section 1. Classification results

Basic question fields:

1. Tree display/paint/repaint/refresh/update, whole or part of the tree.

2. tree initialization, model building.

3. node selection,

4. node operation,

5. node display

6. Mouse event: popupmenu,

7. others: UI, Tooltip,

Keywords:

auto-scrolls, refreshing, customized node, node selection (get the node), Userobject (ToString()), handle, ellipsis, treeTable, PLAF, Component on leaf, Mouse, Safe-mode (Runnable), file structure, home directory, clone, node text

Subject: UIManager, MouseEvent

1. Documents included: Summary.doc, searchSummary.doc,

No

Question

Answer

Index

S/C


Want to different types of nodes, such as different color, icons, modify the size, long name, multi-line, and ellipsis ...

(customized node)

1. Create your own TreeCellRenderer extends DefaultTreeCellRenderer orJLabel, overide getTreeCellRendererComponent method.

2. UI manager

3. text on top of icon

4. dummy node (which is a bad idea; using AllowsChildren instead).

S2, S6,ss13, Ss18, ss28, 5, 7, 8, 15, 23, 24, 25, 26, 29,34,37 40,43,45,52, 54, 55, 61, 63, 65, 73, 70, 78,81,91, 148,154, 155, 157, 162, 167, 169, 171, 172, 174, 181, 182, 188, 191



Tree size:

put in ScrollPane to remove ellipsis

Put tree into ScrollPane instead of Pane

Ss22,2,3, 11, 97, 166, 194


*

Component on leaf

1. CheckBox on leaf 2. Table as leaf

37, 73



The actual expanded state of tree should be restored after refreshing, repaint, whole tree replace

1. Use model.insertNodeInto() and

.removeNodeFromParent();

Get the DefaultTreeModel using Jtree.getModel(); This allows you update the tree without reloading it

2. Not thread safe

3. Create class extends DefaultXXX to inherit all the functions needed.

4. when using ScrollPane

S3,ss5, ss6 ss19, 10, 13, 14, 21, 30, 38, 39,47,48, 50, 71,76, 77, 82, 84, 85, 92, 93, 95, 99, 100, 101,147,156 ,173, 176, 177, 183, 185, 189, 190, 192,



Node retrieval or traversal

GetPathForLocation ...

49, 58, 75, 168, 175



Tree view manipulations (selection, expansion or collapse)

Tree.setSelectionRow(row);

Tree.expandPath(NEW PATH);

Tree.makeVisible(NEW PATH);

Tree.scrollPathToVisible(NEW PATH);

Tree.setSelectionPath(NEW PATH);

2) tree.getSelectionModel(). SetSelectedPath(new TreePath(node)).

Ss1,Ss1119, 35, 44, 46, 79, 96, 98, 150, 161, 186


*

Change a node icon when it is selected

M1: getTreeCellRendererComponent method of your treecellRenderer,

if(sel)

{ this.setIcon(yourselectedicon);}

else

this.setIcon(yournonselectedicon);

M2: tree.isPathSelected(path)

{//set selected icon}

188



Model-view relationship:

Need two or more jtree views of a single tree model, when adding/collapsing happens, all the views should have change their appearance.

Add TreeModelListener to listen to the primary tree, so that they can stay in synch.

S1

17


*

Want to start with the tree expanded/ collapsed completely;

Expanded: Row=0;

while(row<tree.getRowCount()){

tree.expandRow(row);

row++;

}

Collapsed: row=tree.getRowCount()-1;

While(row>=0){

tree.collapseRow(row);

Row--;

}

Ss1, 44, 186, 35


*

Jtree appearance always expanded,

1. Call solution in previous row each time after add a new node

2. add myExpansionLIstener listener to your tree which implements TreeWillExpandListener.

35,



Work-around framework behaviour.

Pls. not collapse child nodes on reload() or on receiving TreeStructureChanged

Have each node include an "expanded" property. Use TreeWillExpandListener to know when the user has clicked on the thing to expand a node, and set the property to "true" at that time.

Then when you do treeStructureChanged, you need walk the tree and expand the nodes that have isExpanded = true yourself, probably using tree.expandPath() method.

36,

ss10, ss14



For a large tree, how to remove/clear all the nodes except the root?

1. root.removeAllChildren(), while I don’t know whether it is ecnomical.

2. create an empty implementation of TreeModel interface and set your tree’s model to that empty implementation

Ss9,


*

When traversing down a tree and hitting a Label that goes out of the viewpoint, it auto-scrolls horizontally to make the Label viewed as fully as possible. How to stop this and make it initialized by the user?

Create a class which extending the Jtree and override the scrollRectToVisible method. Then make a new object with this class and setScrolltoExpand false.

Public class XMLTree extends JTree{

Public XMLTree(TreeNode value){

Super(value);

}

public scrollRectToVisible(Rectangle aRect){

aRect.x=0;

super.scrollRectToVisible(aRect);

}

…….

………..

}

XMLTree newTree = new XMLTree(node);

NewTree.setScrollToExpand(false);

2. urTree.setScrollsOnExpand(false);

Ss10, ss14,



Dynmically loads a tree

Create a tree with info. from database: Querying data from a hashTable to build a tree, want the tree with ascending order.

2. Build the complicated tree

3. node not appear

If you specify a Hashtable as an argument, then the argument is treated as a list of nodes under the root( which is not displayed).

Q2: recursive retrieve info.

Q3: Use TreeWillExpandListener rather than TreeExpandListener, which gives time to the listeners (32).

Ss2, ss7, ss27, 1, 32, 50, 89, 99, 102,



Alphabetical Jtree Node insertion

(ascending order)

HashTable treeStuff = <whatever>

List data = new Vector (treeStuff.values());

Collections.sort(data);

JTree tree = new JTree(data);

JTree(Hashtable value)
Returns a JTree created from a Hashtable which does not display with root.

SS2,80, 103, 165



Multi-roots

1. database solution: eg. Hashtable

2. tree.setRootVisible(false);

SS8, Ss27, 1, 20, 62,


*

Add a tree as node in another jTree.

Provided that they're in the same JVM, and that they're built on DefaultMutableTreeNodes (and DefaultTreeModel), you can simply take the root DefaultMutableTreeNode of the first tree and add it to another JTtree. It will take its children with it.

root=tree.getModel().getRoot();

then use

targetNode = // get the target node you

need to use, maybe the getLastSelectedPathComponent();

targetNode.add(root);

13



How to select and start Editing node;

1)the last child of the root? (node selection)

Or specific node?

TreeModel model = tree.getModel();

Object root = model.getRoot();

int count = root.getChildCount();

node = root.getChildAt(count-1);

path = new TreePath(node.getPath());

tree.setSlectionPath(path);

tree.startEditingAtPath(path);

For specific node: node.getNextNode()

SetRoot: tree.setRoot()/getRoot();

getValue: node.toString();

leaf selection only:

S5, ss4, ss15, ss24. Ss26, 12, 18, 22, 53, 83, 197



Custom editing the node: not support tri-click, only by clicking the delete button

1) Override tri-click method in

DefaultTreeCellRenderer,

2) startEditingAtPath();

31, 178



Node editing

tree.setEditable(false);

Ss12, 4, 181,195,196, 197

S

*

Want to create a Jtree with mutliple root nodes. And use my own FileTreeNode which extending DefaultMutableTreeNode.

Construct the tree with an empty DefaultMutableTreeNode and setRootVisible(false). Then add the customized FileTreeNode to the roots.

Ss8,


*

Don’t want to make the node changeable.

  1. modify TreeCellRenderer

  2. set tree.setEditable(false);

Ss12



How can I make sure that only one node can be single-clicked every time?

TreeName.getSelectionModel().setSelectionMode

(TreeSelectionModel.SINGLE_TREE_SELECTION);

Ss16,



Mouse behaviour

Double click the node to trigger event

double-click is a MouseEvent you need to add a MouseListener to your JTree. Inside the method mouseClicked(MouseEvent e) of the mouse listener you will check for a double click with the following mouse event method
if (e.getClickCount() == 2)
{// some action}

Ss17, 60, 104, 151, 184


*

Mouse enter and exit a node (color change)

See code: it is still related to how to paint a node. So add the function in treeCellRenderer.

104, 184


*

How do I listen to the event changed by the clicking on the tree node?

Sol: For the node selection changes, you need to add a listener for that purpose.(selectionListener)

Ss17



How to traverse a JTree which contains jpeg/gif links and display the images in a separate panel?

Get the image then display in separate panel.

Ss20



Popup menu:

How to rename a node in JTree with the pop up menu?

1. Use tree.startEditingAtPath();

which Selects the node identified by the specified path and initiates editing. The edit-attempt fails if the CellEditor does not allow editing for the specified item.

2. Show a dialog with an entry field for the name, set the name to the node and repaint the tree...

Ss21, ss25, 56


*

JScrollPane and jSplitPane problem:

1. not scroll vertically

2. use scrollPane to two components horizontally.

1. Normally put tree into a scroll pane, then put a scroll pane into a splitPane.

2. JsplitPane.setContinuousLayout(): Sets whether or not the child components are continuously redisplayed and laid out during user intervention

3. For Q2, wrap the whole splitPane into a scrollPane:

splitPane = new JsplitPane(JsplitPane. HORIZONTAL_SPLIT, tree, aPanel);

scrollPane=new JscrollPane(splitPane);

getContentPane().add(scrollPane);

Ss22, 3,

166



set the pop-up menu;

show popup menu.

Tree.add(jpopupMenu);

Tree.addMouseListener(this){

Public void mouseReleased (MouseEvent e){

jPopupMenu.show (e.getX(), e.getY());

}}

show: use getSelectionRow() and .isPopupTrigger() together.

Ss25,56



Set the width of the tree? Is there any method for getRowWidth()?

I use Rowà tree. GetRowForLocation(e.getX(),e.getY());

tree.getRowBounds(rowNo) return the rectangle that the renderer draws in. You can set the preferred width of the tree to the width of the rectangle.

6


*

setTreeSize? Although tried setSize(), setMaximumSize(), setBound(), no result

Try placing the tree into a JscrollPane, this way, the scrollPane will simply add scrollbars to accommodate.

11



Userobject: 1. have multiple variables eg. institution Id and Institution Name

2. rename a custom object

3. hiding data (client data)

Class MyObject{

int Id;

String Name;

public MyObject(int Id, String Name){

this.Id = Id;

this.Name = Name;

};

public int myId{ return this.Id}

public String myName{return

this.myName}

}

….

//When you need the object:

Object obj = node.getUserObject();

If(obj instanceof MyObject){

System.out.println(obj.myId);

}

Q2:myObject=node.toString();

myObject.changeVable();

9, 28, 33, 41, 64, 69, 86, 160,


*

Handle:

A. hide the "+" symbol (Hide handles)

B. make handle for each node when created.

1. Tree.setShowsRootHandles(false);

2. ui=(BasicTreeUI) tree.getUI();

ui.setExpandedIcon(null);

ui.setCollapsedIcon(null);

B. make dummy child.

15, 23, 45, 155


*

Display only directories (hide leaf), file structure

public boolean hasSubDirs() {

File subfiles[] = listFiles();

If(subfiles == null)

return false;

for(int i = 0; i < subfiles.length;) {

if (subfiles[k].isDirectory())

// add to the tree

return true;

else

//add to the table

return false;

}

return false;

}

34, 191


*

I got a Jtree object I want to display on two different panes of a JTabPane. But only the tree in one panel worked well, the other not.

The problem was caused because you was trying to add the same JTree object to two different panel components. Making the shared object a tree model that is shared between to Tree objects works wonderfully.

17,


*

Tree navigation with buttons (up)

ActionPerformed(ActionEvent e){

String c=e.getActionCommand();

int row= tree.getSelectionRow

(e.getX(), e.getY());

if(row>0)

tree.setSelectionRow(row-1);

}

19



Find the index of the node dynamically

1. get the selected node (tree.getSelectionPath)

2. ((DMTN)node). GetIndex();

149


*

Expand folder down

JTree myJTree = new JTree();

MetalTreeUI myJTreeUI = new MetalTreeUI()

myJTree.setUI((TreeUI)(myJTreeUI));

myJTreeUI.setRightChildIndent(0);

myJTreeUI.setLeftChildIndent(0);

myJTree.putClientProperty("JTree.lineStyle", "None");

myJTree.putClientProperty("Tree.hash", new ColorUIResource(Color.white));

152



Alternative view of Tree:

see nodes horizontally, not vertically.

See code:

2. rewrite the myTreeUI delegate

68, 152, 153, 159, 170



General question

1)The real example of jtree

1) anything need to classify.

158


*

Show Tooltip

1) For tree node.

ToolTipManager.sharedInstance().registerComponent( aComp);

63, 162.



Exploring format (treeTable)


163

C


Height between nodes

tree.setRowHeight(20); 20 pixels

164

S

*

Use checkBox for node

See Code:

171


*

set/change the color of lineStyle

UIManager.put("Tree.hash", Color.magenta);

172


*

Traverse all nodes

postorderEnueration(),

depthFirstEnumeration(),

breadthFirstEnumeration()

175,

S


Look and Feel(PLAF)

1)Import LAF

2) Set Window LAF

1) the swing package name has changed in JDK 1.2, pls. Be consistant with the change.

2)try{

UIManager.setLookAndFeel

("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");

SwingUtilities.updateComponentTreeUI(workSpaceJtree);

}catch(Throwable e) {System.out.println(e);}

66, 187



Mouse related

1. Selection

1. Implement the treeSelectionLIstener interface, then tree will get told which node is selected.

42



Antipatterns:

open node detection

self-def isLeaf

1. customize TreeNode to keep track of its state (E/C)

2. add TreeWillExpandListener to update the state of the node.

3. use a recursive method to collect all expanded nodes. (see code)

51,


*

Create invisible nodes in the tree

Dummy node

52,


Tree background image Tree transparent

Subclass DefaultTreeCellRenderer, set tree.setOpaque(false); myTreeCellRenderer.setBackground(null);

59, 193



See Below


Tree made from home directory

1. Create a root for your tree;

2. File[] roots = File.listRoots(); which lists the available filesystem roots.( eg. A,C,D disks);

3. add this roots to your tree-root.

67


*

Change the node content dynamically

(node text)

The text of a node is based on the userObject, so: node.setUserObject();

69, 86,


*

Dynamic change color

1)Change the color the selected node's parent

1)Parent = Node. GetParent();

2)The color is determined by the TreeCellRenderer, so do it there.

70,78



Duplicate a tree (clone)

Try cloning the treeModel of the tree, because it is the treemodel who contains the data. Another way is to clone the root node of your tree

74



getDefaultTreeModel

It is static method, so use tree.getDefaultTreeModel(). Besides, it is protected, so only can be used by its subClasses. Usually we use tree.getModel();

90,


*

Add parent nodes at runtime

There is no parent node in tree except the root node which may or may not be visible. So just use insertNodeInto();

92



Undo in Jtree

1)Do a stack of tree models and pop the stack to achieve undo, but the problem is the amount of storage required to save all those tree models.

2)Creating a new tree node class that has undo/redo capability. The user could undo and redo by node and the tree as a whole would have fine-grained undo/redo built-in.

94,


*

JSplitPane not behaving correctly (size)

SetPreferredSize() on your left (tree) part.

97




Section 2. Collected questions and answers

1. JTree(HashTable value) what is the use of this?

May I pass Hashtable to Jtree().That means I don't want root node?

Sol: If you specify a Hashtable as an argument, then the argument is treated as a list of nodes under the root node (which is not displayed).

JTree(Hashtable value)
Returns a JTree created from a Hashtable which does not display with root.

2. I have a Jtree in which I dynamically create the nodes when expanded. Sometimes the nodes dont show the entire text but show up with ellipsis in the end. If I close the tree and reopen it at this point, sometimes it shows the labels of the nodes rihgt. Is there a way to make sure that the ellipsis dont show up? In other words, how do I make sure that the text on the Nodes appears properly all the time?

Sol: JTree's treeDidChange() method should get rid of this unsightly ellipsis. Besides, you need call your tree model's nodeStructureChanged() method.

public void treeDidChange()
Sent when the tree has changed enough that we need to resize the bounds, but not enough that we need to remove the expanded node set (e.g nodes were expanded or collapsed, or nodes were inserted into the tree)

public void nodeStructureChanged(TreeNode node)
Invoke this method if you've totally changed the children of node and its childrens children... This will post a treeStructureChanged event.

3. I have a split pane which contains two components, Jtree(scrollpane) and List control. Here when the tree grows bigger, I wish the scroll bar can control both of the two components together. How to do it?

Sol: wrap the whole splitPane into a ScrollPane:



splitPane = new JsplitPane(JsplitPane.HORIZONTAL_SPLIT, tree, otherPanel);

scrollPane = new JscrollPane(splitPane);

getContentPane().add(scrollPane); // this class extends Jframe

4. I want to make the tree node editable, I would like to make the node renamable. How Could I get the edited value?

Sol: tree.setEditable makes the nodes editable, to get the edited value:

yourTree.setEditable(true) ;
....
functionWhereYouDealWithEditingNodes()
{
TreePath tPath = yourTree.getEditingPath() ;
DefaultMutableTreeNode editNode
=(DefaultMutableTreeNode)tPath.getLastPathComponent() ;
}

5. Different nodes with different icons in a single tree? (JTree Leaf Icons )

Sol: The solution lies with how you implement getTreeCellRendererComponent() of your custom TreeCellRenderer. Whatever icon you set within this method determines the graphic painted in the tree view.

6. Set the width of the tree: Is there any method for getRowWidth()?

I use Rowà tree. getRowForLocation(e.getX(),e.getY());

Sol: tree.getRowBounds(rowNo) return the rectangle that the renderer draws in. You can set the preferred width of the tree to the width of the rectangle.

7. Iam trying to make a tree that will have more than one kind of icon to represent the leaf-nods,I would lika to have different icons for different nodtypes

Is it possible?? If it is how can i do it? (different icon for different nodes)

Sol: see before.

8. Can I change icons in JTree?

Sol: See before

9.Jtree's node userobject

I want to know if I can have multiple variables added to the node's Userobject. eg. institution Id and Institution Name

Sol: Yes, just build an object that encapsulates this data and use it as your user object. in chapter 17 in my textbook, http://www.spindoczine.com/sbe .

Class MyObject{

int Id;

String Name;

public MyObject(int Id, String Name){

this.Id = Id;

this.Name = Name;

};

public int myId{ return this.Id}

public String myName{ return this.myName}

}

….

//When you need the object:

Object obj = node.getUserObject();

If(obj instanceof MyObject){

System.out.println(obj.myId);

}

10. 1000 Nodes added to JTree not visible

I am developing an appln using JTree. And it uses DefaultTreeModel. The nodes are DefaultMutableTreeNodes constructed out of some custom objects. And i use a class subclassed from DefaultCellRenderer to paint my nodes. My client receives some 1000 objects from the server. And they have to be added to my JTree and set to expanded state.....i.e. it is an Expand All situation. The problem is the time taken to paint is enormous and comes to 180 to 200 seconds which is not affordable. And only after adding all the nodes, i can visually see the nodes that have been added to JTree....

As and when i receive objects from the server, i am adding the corresponding node to the JTree and call JTree's scrollPathTovisible method to the node added. But while adding to the JTree, i am unable to see the nodes on the tree.....I want to have the visual effect of the nodes being added to the tree.... My application class extends from JFrame.

Sol:

The tree will not get refreshed until all the 1000 records are processed.The following code somewhat helps...

public void treeExpanded(TreeExpansionEvent tee)

{

final DefaultMutableTreeNode node = getTreeNode(tee.getPath());

Thread thread = new Thread() {

public void run()

{

if(condition !!! )

{

Runnable runnable = new Runnable() {

public void run()

{

m_model.reload(node);

}

};

SwingUtilities.invokeLater(runnable);

}

}

}; //end of anonymous class

thread.start();

}// end treeExpanded

11. How to control JTree`s size ??

I `m creating a windows explorer application using the JTree. This JTree is added to a panel, p1. This panel is added to another panel, p2.Lastly, I add p2 to the frame ,which contained other components as well. Since there`s a space constraint for p2 in the frame,

i tried to resize the JTree and p1 so that it will fit into the frame.The out put is a JTree which is far too big for user to scroll down the whole tree.I `ve tried almost everything i can think of : setSize(), setMaximumSize(), setBounds() but to no avail.I found that the JTree size is still the same ,no matter what i do.Anybody got any tips?

Sol: Try placing the JTree into a JScrollPane. This way, no matter how large the Tree gets, the scrollpane will simply add scrollbars to accomidate.

12. Can't select JTree node when window opens

Sol: You can select at the constructor part. It initializes the look of the tree.

public class SelectedTree extends JFrame{
public SelectedTree(){
super("Test for SelectedTree");
DefaultMutableTreeNode root = new DefaultMutableTreeNode("root");
DefaultMutableTreeNode child1 = new DefaultMutableTreeNode("child 1");
root.add(child1);
JTree tree = new JTree(root);
tree.setEditable(true);
TreePath path = new TreePath(child1.getPath());
tree.setSelectionPath(path);
}
}

13. How to add a JTree as node in another JTree

I have an instance of JTree, which is built on a TreeModel. I would like to add this JTree as a node to another JTree. Is it possible? If not, is there any other way to get this done?

Sol: Provided that they're in the same JVM, and that they're built on DefaultMutableTreeNodes (and DefaultTreeModel), you can simply take the root DefaultMutableTreeNode of the first tree and add it to another JTtree. It will take its children with it.

DefaultMutableTreeNode root = (DefaultMutableTreeNode)

tree.getModel().getRoot();

then use .

DefaultMutableTreeNode targetNode = // get the target node you

need to use, maybe the getLastSelectedPathComponent();

targetNode.add(root);

14. Clearing the removed leaf or node in an Expanded JTree

I am using a level 3 JTree In our project.Based on certain condition I have to remove certain leafs,or nodes form JTree. When the JTree is collapsed it works fine but when the JTree is in expanded condition, after removing the leaf or node it still appears in the JTree although it is actually removed form the tree.

I have tried several methods like

tree.validate()

clearSelection()

I also tried first to collapse the particular node then remove

the leaf & then again expand but in vain.

Sol: Your tree model needs to call nodeStructureChanged(node), where the parameter "node" is the node that has had children added, removed, changed, or what have you.

Or Use removeNodeFromParent(). If you don’t use the defaultModel, you need to create your own.

15. Want to Hide the "+" symbol (what you click on to expand/compress a line in the JTree) that appears next to a node that is a child of another node, for all Look and Feels. Also hide the drawing of lines connecting the "+" symbols together.

Sol: tree.setShowsRootHandles(false);

16. How to Display a leaf row with the text on top of the icon, instead of the text displaying to the right of the icon?

Sol: To overlay text over an icon you can do something like this:

public class TextIcons extends MetalIconFactory.TreeLeafIcon {

protected String label;

private static Hashtable labels;

protected TextIcons() {

}

public void paintIcon(Component c, Graphics g, int x, int y) {

super.paintIcon( c, g, x, y );

if (label != null) {

FontMetrics fm = g.getFontMetrics();

int offsetX = (getIconWidth() - fm.stringWidth(label)) /2;

int offsetY = (getIconHeight() - fm.getHeight()) /2 - 2;

g.drawString(label, x + offsetX ,

y + offsetY + fm.getHeight());

}

}

public static Icon getIcon(String str) {

if (labels == null) {

labels = new Hashtable();

setDefaultSet();

}

TextIcons icon = new TextIcons();

icon.label = (String)labels.get(str);

return icon;

}

public static void setLabelSet(String ext, String label) {

if (labels == null) {

labels = new Hashtable();

setDefaultSet();

}

labels.put(ext, label);

}

private static void setDefaultSet() {

labels.put("c" ,"C");

labels.put("java" ,"J");

labels.put("html" ,"H");

labels.put("htm" ,"H");

// and so on

/*

labels.put("txt" ,"TXT");

labels.put("TXT" ,"TXT");

labels.put("cc" ,"C++");

labels.put("C" ,"C++");

labels.put("cpp" ,"C++");

labels.put("exe" ,"BIN");

labels.put("class" ,"BIN");

labels.put("gif" ,"GIF");

labels.put("GIF" ,"GIF");

labels.put("", "");

*/

}

}

this code is extracted from http://www2.gol.com/users/tame/swing/examples/JTreeExamples2.html

17. JTree oddity

I got a JTree object I want to display on two different panes of a JTabPane. Each pane has a panel where the JTree will go. Both panels are indentical and start with a simple label saying the tree data is still building. Each pane implements Observer and when the tree has completed loading (from a SQL database), it notfies it's observers. So far so good. Here's the problem. On one pane, the tree shows up and works
great, ie, it responds to mouse clicks. On the other pane, the tree shows up only occasioanlly and when it does, it doesn't repsond to mouse clicks. Additionally, if I switch to a different pane and come back the tree is gone. Does anyone have an idea what is going on here?

Sol: The problem was caused because you was trying to add the same JTree object to two different panel components. Making the shared object a tree model that is shared between to Tree objects works wonderfully.

18. Select in JTree

I am trying to set the selected item in a JTree from code using JTree.setSelectionPath.

However, this selection is not indicated on the JTree, even if I do repaint, updateUI,

etc. If I call setSelectedPath, and then call getLastSelectionComponent, I get

the correct path, so JTree is getting the selection, it just isn't indicating it

graphically.

Sol: Make sure you selected the right path:

JTree tree = new JTree();

tree.setEditable(true);

DefaultTreeModel model = (DefaultTreeModel)(tree.getModel());

DefaultMutableTreeNode root = (DefaultMutableTreeNode) (model.getRoot());

DefaultMutableTreeNode child1 = (DefaultMutableTreeNode) (root.getNextNode()); //find any node you like

TreePath path = new TreePath(child1.getPath());

tree.setSelectionPath(path);

19. JTree navigation with buttons

I'd like to navigate my JTree using buttons rather than the cursor keys. When I click the "Up" button, I would like the JTree to act as if I had clicked the "up" cursor key by selecting the node just above the currently selected node.

Sol: actionPerformed(ActionEvent e){

String command = e.getActionCommand();

int selRow = tree.getSelectionRow(e.getX(), e.getY());

if(selRow>0)

tree.getSelectionRow(selRow-1);

}

20. I'd like to add more than one root node to my JTree.

I tried the following :

JTree jTree1;

DefaultMutableTreeNode top[] = new DefaultMutableTreeNode[2];

top[0] = new DefaultMutableTreeNode("root1");

top[1] = new DefaultMutableTreeNode("root2");

jTree1 = new JTree(top);

DefaultMutableTreeNode c1= new DefaultMutableTreeNode("c1");

DefaultMutableTreeNode c2= new DefaultMutableTreeNode("c2");

DefaultMutableTreeNode c3= new DefaultMutableTreeNode("c3");

top[0].add(c1);

top[0].add(c2);

top[0].add(c3);



But, the thing is the child nodes c1,c2,c3 are not added to the

node 'root1' (top[0]). Why it is not working? how to add child

nodes to the tree which is having 2 root nodes. Thanks in

advance.

Sol:By definition a tree can only have one root node. To get a tree

with the _appearance_ of multiple root nodes, hide the root node

by calling setRootVisible(false) on the JTree.

tree = new JTree();

DefaultTreeModel model = (DefaultTreeModel)tree.getModel();

DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();

tree.setRootVisible(false);

21. Refreshing problems with JTree

I have a problem i am trying to solve for days. Can someone help me, i have headaches...

I have a class extending JTree, and i affect it my TreeModel, I don't use the DefaulTreeModel. I want to delete a node, i managed to delete it in the DataBase

and in my TreeModel but it is still here in the JTree architecture (same problem with rename). I implements this in my TreeModel, i have to prevent all my JTree listeners

Sol: derive your TreeModel from DefaultTreeModel and override some methods.

copy some methods from DefaultTreeModel into your own TreeModel. You will need:

1. the methods that will be called from "outside" to perform the

changes on your nodes hierarchy:

insertNodeInto, nodeChanged, removeNodeFromParent

2. the methods to do the internal work:

nodesChanged, nodeStructureChanged, nodesWereInserted,

nodesWereRemoved

3. the corresponding fire... methods:

fireTreeNodesChanged, fireTreeNodesInserted,

fireTreeNodesRemoved, fireTreeStructureChanged

If you have done that, no listeners will be necessary.

Note: it worked after he implements his own fire methods :

fireTreeNodesChanged

fireTreeNodesRemoved

22. Jtree Selection question

I need to be able to select a node under java and a node under the javaprogram so that the javaprogram is started with the selected jdk.

Sol: there are 4 methods to select a node :

setSelectionPath(TreePath path) //Selects the node identified by the specified path.

setSelectionPaths(TreePath[] paths)//Selects the nodes identified by the specified array of paths.

void setSelectionRow(int row)//Selects the node at the specified row in the display.

void setSelectionRows(int[] rows)//Selects the nodes corresponding to each of the specified rows in the display

23. Change color of a node in JTreeTable

I have created a JTreeTable and to the root node i add nodes like - fruit, vegetables, etc and under fruit i have added 5 other nodes. I want the background color for the fruit,

vegetables, etc nodes to be of a different color. And the color in the second column should also be according to the color of nodes in Jtree...

Sol:U need to create TreeCellRenderer that extends DefaultTreeCellRenderer. ANd overwrite getTreeCellRendere(...)

public Component getTreeCellRendererComponent(…) {

ImageIcon icon;

Color red = new Color(255, 0, 0);

super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);

if (value instanceOf Fruit)

setForeground(new Color(255, 0, 0))

}

24. JTree.setShowsRootHandles(boolean) but for non-root/top handles???

I need to get rid of the handles for all levels of a JTree, not just the root/top level.There is a JTree.setShowsRootHandles(boolean) method, but it only works for the root/top level.

Sol:

import javax.swing.plat.basic.BasicTreeUI;

BasicTreeUI ui = ( BasicTreeUI )tree.getUI();

ui.setExpandedIcon( null );

ui.setCollapsedIcon( null );

25. HowTo: Control expand/collapse Icon in JTree

I'd like to be able to set the expand/collapse icon in the JTree. I know I can set the actual Icon, but I want to set if it is displayed or not. I create a JTree but don't fully populate it due to performance reasons. I want my nodes to show the "+" sign if they have children "in the database", but the JTree won't know about them until the user tries to expand that node. I know I could add a dummy node under any nodes that have children,

but is there a more elegent way? I don't like deleting the dummy nodes when the user expands one of these.

Sol: It seems only dummy nodes can work this out. Even the textbook use this method.

26. TreeCellRenderer with dynamic JTree

I have a JTree which adding child nodes while user click on a node. The information is from the database. And I am expecting to use my own icon to replace the JTree icon.

Sol: It should work if you are sure everything is right in your TreeCellRenderer, and then use getTreeCellRenderer.

27. Customizing selection in a JTree

I need to customize the way a JTree selection behaves in the following way:

1. A user should be able to select multiple leaves, and leaves only.

2. Selected leaves can only be part of a single "folder" (non-leaf node)

The problem is that the selection is handled by the JTree and I can only get a notification the the selection HAS CHANGED. I can't prevent the change.... Adding a mouse (or a keyboard) listener to the JTree does not help, since it has already a mouse listener that triggers the selection change.

Sol: The following code should allow leaf selection only:

public class LeafOnlyTreeSelectionModel extends

DefaultTreeSelectionModel {

public void addSelectionPath(TreePath path)

{

DefaultMutableTreeNode lastComp =

(DefaultMutableTreeNode)path.getLastPathComponent();

if (lastComp.isLeaf()) {

super.addSelectionPath(path);

}

}

public void addSelectionPaths(TreePath[] paths)

{

for (int i = 0 ; i < paths.length ; i++) {

DefaultMutableTreeNode lastComp =

(DefaultMutableTreeNode)paths.getLastPathComponent();

if (!lastComp.isLeaf()) {

return;

}

}

super.addSelectionPaths(paths);

}

public void setSelectionPath(TreePath path)

{

DefaultMutableTreeNode lastComp =

(DefaultMutableTreeNode)path.getLastPathComponent();

if (lastComp.isLeaf()) {

super.setSelectionPath(path);

}

}

public void setSelectionPaths(TreePath[] paths)

{

for (int i = 0 ; i < paths.length ; i++) {

DefaultMutableTreeNode lastComp =

(DefaultMutableTreeNode)paths.getLastPathComponent();

if (!lastComp.isLeaf()) {

return;

}

}

super.setSelectionPaths(paths);

}

}

28. rename a custom object in a JTree

i work with a JTree that contains customs objects. So far its not a problem. I have also overwrite the toString() method in my custom class to make the JTree able to show a name for my object (Its just a name from the record inside my class).

The problem is: After finish renaming I want to store the new name in the appropriate data field in my custom class! Please help!

Sol: use to String() to find your custom class, then use changeValue() (which should be in your custom class) to change the value.

29. Very lond JTree Node names : How to wrap?

Sol: the label associated with a TreeNode is configured by a TreeCellRenderer. So, you need to create your own renderer and use it in your JTree.

30. JTree - Expanded node set to collapse state without doing anything !!!!

Sol: By default, it will keep the former expanded status rather than collapsing it. Note that when you do something, use extends DefaultXXX, then you can inherit all the characteristics of the classes. See my code for example.

31. Replacing JTree Nodes

I need some help with the renaming or replacing of JTree nodes.We display the database data as JTree and the user can select any node from the tree and edit the details for that node.If the user chooses to change the name,how this new name be shown on

instead of the previous name?

Sol: If you want to change the text that appears on the screen? Just have to change the user object that's in the node. Then in your tree model, just call "NodeChanged(node)".

32. The fallowing code is fully runnable and shows my problem. I'm writing an application which creates childes of a node from a database. Because of this the application reads the database on every TreeExpansionEvent, deletes the old nodes and adds the new ones. My problem: I just can't select one of this newly created nodes. If I try to do so then the treeExpanded methode gets called. Also when I try to collaps the tree node this happens. I really hope that someone can help me. Here's the source code, just compile and run it to see what I mean (try to select a node with the text "bla"):

Sol: I had to try this, because it didn't agree with what I was finding in my JTree application. But after I compiled and ran your program, I realized you aren't doing what I'm doing. My program uses a TreeWillExpandListener rather than a TreeExpansionListener. That gives my program time to fill in the nodes when it finds the user has asked to expand their parent.

So try TreeWillExpandListener instead.

33. JTree and hiding data

Is there any way by which I can set the particular database ID for that name to the JTree as a, suppose, hidden variable.This way I can do the data manipulation using the ID but the user will be seeing the name only.

Sol: Defining toString() method will return the name, that's what the user will see on the screen, you can write other methods for the class that use the database ID.

34. How to hide a leaf in JTree,Display leaves in JTable on right side Panel like in Windows Explorer

I am making a WIndows explorer like thing and I want to show the "leaf nodes" of JTree in JTable in the Right side panel and I don't want to show the Leaves in the JTree, only Nodes who have children are displayed in JTree and nodes which doesnot have childnode are displayed in JTable.

Sol: if it's a directory i.e which have children bring it into the explorer view.... else if it has null children bring into the table...

public boolean hasSubDirs() {

File subfiles[] = listFiles();

if(subfiles == null)

return false;

for(int i = 0; i < subfiles.length;) {

if (subfiles[k].isDirectory())

// add to the tree

return true;

else

//add to the table

return false;

}

return false;

}

35. JTree apperance always expanded ??

I'm looking for a possibility that a my JTree will always be expanded. My problem is, that after inserting new nodes into the second stage of my JTree, I can't see my leafs at the third stage anymore. I have to double-click on the nodes in the second

stage. Is there any way, that the appearance of my JTree will always be expanded totally. Right now I'm always using the reload-method of the DefaultTreeModel-class after inserting new leafs into the model. is there any better way to fix my problem.

Sol: method1: You could call this function each time after you add a new node:

private void expandAll()

{

int row=0;

while(row < getRowCount())

{

expandRow(row);

row++;

}

}

method2: you need to add this Listener to your JTree.

class MyExpansionListener implements javax.swing.event.TreeWillExpandListener

{

public void treeWillCollapse(TreeExpansionEvent

event) throws ExpandVetoException

{

throw new ExpandVetoException(event);

}

public void treeWillExpand(TreeExpansionEvent event)

{}

}

36. Needing custom JTree, TreeStructureChanged behaviour

Has anybody developed a customised JTree component that does not collapse child nodes on reload() or on receiving TreeStructureChanged (same thing).

Our application needs to refresh the JTree view (rather its hidden internal cache) to reflect changes in the model, but this occurs as a synchronisation with the database. So I can duplicate the usual TreeNodeInserted, TreeNodeRemoved actions that occurred. So after reloading the effected branch into the TreeModel its fires treeStructureChanged, which is fine but this collapses any expanded children by default, which effectively

hides the changes and isn’t what our users want. So what I really need is a customised JTree (TreeModelHandler) & supporting BasicTreeUI that updates descendants in response to a treeStructureChanged event, So all the children of the event won't collapse!

Sol: To do that yourself, I think you would have to have each node include an "expanded" property. You can use a TreeWillExpand listener to know when the user has clicked on the thingy to expand a node, and set the property to "true" at that time.

Then when you do treeStructureChanged, you would have to walk the tree and expand the nodes that have isExpanded = true yourself, probably using JTree's expandPath method.

37. JTree with CheckBoxes on Leafs

I created a JTree using my own data (no database or file systems) and I was able to put Checkboxes on the leaves, but I'm having a hard time controlling when the boxes get checked and unchecked.

Sol: 1. In my limited experience, it has been very bad to mix AWT and Swing components liberally like that. 2. JTree uses the TreeCellRenderer as a way to stamp regions on the screen, it merely uses the paint method of the Component given by getTreeCellRendererComponent to paint the appropriate region. The checkbox you're seeing on the screen in the JTree is not an actual component, i.e. it doesn't actually receive mouse events. You will have to catch the MouseEvents coming to the JTree by

adding a MouseListener to the JTree. The JTree does this for performance reasons as having a 100's of components takes up quite a bit of processing time.

final JTree tree = ...;

MouseListener ml = new MouseAdapter() {

public void mousePressed(MouseEvent e) {

int selRow = tree.getRowForLocation(e.getX(), e.getY());

TreePath selPath = tree.getPathForLocation(e.getX(),

e.getY());

if(selRow != -1) {

if(e.getClickCount() == 1) {

mySingleClick(selRow, selPath);

}

else if(e.getClickCount() == 2) {

myDoubleClick(selRow, selPath);

}

}

}

};

tree.addMouseListener(ml);

You know which node the user clicked on, so you can then change

how the JCheckbox is configured when handed to the JTree by

getCellRendererComponent.

public Component getCellRendererComponent(...){

// if you use the typical TreeNode usage

TreeNode node = (TreeNode)value;

Object myObject = node.getUserObject();

if(myObject.isChecked()){

checkBox.setSelected(true);

}else{

checkBox.setSelected(false);

}

return checkBox;

}

38. how to delete a node from a JTree

Sol: In place of stree.removeSelectionPath(stree.getSelectionPath());

Now, get default tree model-

DefaultTreeModel model = (DefaultTreeModel)stree.getModel();

Get last selected node (that you want to delete)

TreeNode node = (TreeNode)stree.getSelectionPath().getLastPathComponent();

Now, remove it from its parent-

model.removeNodeFromParent(node);

39. How can i refresh the JTree displayed.

Sol: I don't use repaint() to do that.

When my tree model (which extends DefaultTreeModel) adds a new child to node X, it simply calls NodeStructureChanged(X). Likewise there's NodeChanged(X) if you just changed the displayed text of node X, and so on. It works just fine.

40. JTree Icons? (customize the icons)

I am using JTree for the first time.When i create JTree with some structures i actually want my own icons(.gifs) instead of the default ones.I mean based on the category i want to change the icons.

Sol: see before

41. JTree and JApplet

I am adding JTree in JApplet. And, I am also populating the JTree with data. But, while loading this applet in the browser(internet explorer), the jtree is not coming.

Sol: One possible problem is your data must have the toString() method.

42. Mouse selection in a JTree

I am creating a subclass of JTree which has a Mouselistener. On receiving a MouseDragged event, I execute the following code:

int x = mouseEvent.getX();

int y = mouseEvent.getY();

int minRow = getMinSelectionRow();

int maxRow = getMaxSelectionRow();

int thisRow = getRowForLocation(x,y);

int initRow = minRow < thisRow ? minRow: maxRow;

setSelectionInterval(initRow, thisRow);

However, this has the unpleasant side effect of messing up the selection

when the mouse wanders out of the JTree while still clicked.

Sol: Implement the TreeSelectionListener interface, then when you click on your node, the object that implements that interface gets told what node was selected.

public class WhatWasClicked implements TreeSelectionListener {

...

// in initialization:

yourJTree.addTreeSelectionListener(this);

// to implement TreeSelectionListener:

public void valueChanged(TreeSelectionEvent e) {

TreePath selPath = e.getNewLeadSelectionPath();

if (selPath == null) {

// selection changed, nothing is selected now

}

else {

selectedNode = (YourNode)selPath.getLastPathComponent();

}

}

43. Different leaf icons in JTree?

Sol: see before.

44. I have created a JTree which when clicked shows me the inside path..but i want the entire Tree structure(expanded form) to be shown initially without any click on Mutable Tree Node or something..can one urgently help me on this...

Sol: JTree has a method expandRow(). int row=0; while(row <tree.getRowCount()), call this method.

45. JTree root handles problem

I'm using a JTree to dynamically display data from database requests. ie The tree starts empty and grows using database queries as tree expansion events are caught. I would like each node in the tree to display a root handle, even though the node may presently have no children. I have called JTree's setShowsRootHandles(true) and the defaultTreeModel's setAskAllowsChildren(true) in the constructor but this only shows the root handle for a node after I have expanded the node by double clicking on it.

Sol: You can't get the handles to show unless you place at least one dummy/fake TreeNode under each. As you dynamically expand a branch, you'll need to recognize and remove the fake node.

46. JTree : setSelectedNode()

The user can add to or delete to the JTree in my application.I want to show the recently added node as selected ( highlighted). In case of deletion, I need to show the previous as the selected one.

Sol: see sample-TreeTest.java



47. Remember JTree Open/Close Paths

My current project requires the use of a JTree. Basically I have a list of files and their respective directories, or which are linked in the obvious ways.

Basically, how do I refresh the JTree with the all the data but retain the path structure that the user may have opened/closed?

Sol: Use the insert and remove methods from the tree model. So it must not be updated and the tree structure will not be changed. Another way is to use the reload method with the tree node. Maybe you can also use treeDidChange() method of the tree.

48. JTree refresh problem

I have a JTree that is dynamicly built from a database. After the user enters a new node, the update is made to the database and then the JTree is refreshed with the following code. My disired result is that the node selected at the time of insertion will continue to be selected after insertion. It's not working. Note that the Tree is rebuilt correctly and the only thing not working is the selection of the last selected node before the refresh.

Sol: you need to reload your tree model too. using treeModel.reload(root), Tree.expandPath(treePath) and JTree.setSelectionPath should be enough.

49. Selecting a particular node in a JTree automatically

I have an application which uses a JTree. The tree is built based on the data in the database and uses DefaultMutableTreeNode. If the user wants to modify the record(once after the tree has been built and the press of a button), the tree should expand to the node earlier selected. The tree has a root, child1Level, child2Level nodes. I tried through the expandRow(int), but this one expands but to select a node at child2Level, I do not find any method. When I use addSelectionRow(int), it selects in the child1Level nodes, but not in the child2Level nodes. Kindly give me a way to indicate a integer number to reach the child2Level. Or give me a way to build a TreePath from an existing JTree based on the root info (like child1Level, child2Level).

Sol: One thing that I have found useful is that each tree node, DefaultMutableTreeNode, allows me to add a user object. This user object allows me to add attributes to the tree node to clearly identify each. Having identified the tree node that I want to select and show I do the following.

50.I was trying to create a Explorer-like widget, ti display the file structure into a JTree (cf.MS Explorer). It's my first JTree use, but I found how to create nodes and add children to existing nodes.My problem is as follows :

I don't want to create the whole tree before displaying it. It should be too long to process (process all directories recursively should take a very long time and many ressources!). So, I'd like the tree to expand only when necessary. Just display current directories and files, and add nodes when opening a directory.

My problem, is that if no node is added to a directory node, it is not displayed as a directory (icon) but like a file. I tried to set the "setAllowsChildren(true)" to my DefaultMutableTreeNodes, but it does not work. Nodes are only displayed as directories if I explicitly add at least one node to them!

Sol: I implemented TreeWillExpandListener to know when the user clicked on the thing to expand the node, then filled in the children. I assume you're doing something like that. I had the same problem of how to know whether there are children, and I solved it by having my node objects override the IsLeaf() method. First approximation is to have this always return false, so the user gets somewhere to click to expand the node. Second approximation is to store a flag in the node object so that when the user does expand it, it remembers whether there were actually any children, and if there weren't then return true (until the user does add children).

51. Detecting all the open nodes in th Jtree

Is there a possibility to know the list of nodes opened in the tree.This is exactly,when we expand the tree,i need to know the index or the values of all the nodes which are expanded under the tree i.e from the root.

Sol: Couple of things:

1. You need your own custom TreeNode that would keep track of its state (expanded/collapsed).

2. add a TreeWillExpandedListener to your tree which would update the state (expanded/collapsed) of the node corresponding to the path sent in 'TreeExpansionEvent' that gets passed to treeWillExpand/treeWillCollapse.

3. Have a recursive method to collect all the expanded nodes.

Here is a sample:

Vector expandedNodes = new Vector();

getExpandedNodes(MyDefaultMutableTreeNode root, expandedNodes);

// Here is the method,

void getExpandedNodes(MyDefaultMutableTreeNode pNode, Vector

eNodes)

{

Enumeration enum = pNode.children();

while(enum.hasMoreElements()) {

MyDefaultMutableTreeNode cNode =

(MyDefaultMutableTreeNode)enum.nextElement();

if(cNode.isExpanded()) {

// add it to the list

eNodes.addElement(cNode);

getExpandedNodes(cNode, eNodes);

} else {

// if you want to consider the nodes under this

// non-expanded node, you need to uncomment the line

// below

// getExpandedNodes(cNode, eNodes);

}

}

return eNodes;

}

52. How to create invisible nodes in the Jtree ?

Sol: see before.

53. Question on Jtree---node editable

Sol: see before.

54. color changing in JTree

Sol: see before.

55. URGENT!! setting icons for JTree

Sol: see before

56. JPopupMenu won't display in JTree

I am attempting to extend the JTree class to include a built in JPopupMenu, but have run into some difficulties. I am able to attach the JPopupMenu to the JTree ok, and have it triggered on the right mouse-click(or, more precisely, on the popupTrigger). The problem is that it only displays if I right-click near the edge of the tree. I have seen messages about similar problems, but so far have not been able to find a solution. One suggested

calling setLightweightPopup(false). After this call, the popup displays, but without any of the menu items. I have implemented a simple tree and popup successfully, but for some reason I am missing something here. I have tested this under JDK 1.2.1,

1.2.2 and 1.3.0. Here is the class:

public class UserTree extends JTree {

private UserTreeModel um;

private SecurityTreeModel sm;

private JMenuItem cutItem, copyItem, pasteItem, deleteItem;

private JPopupMenu popupMenu;

public UserTree() {

um = new UserTreeModel();

this.setModel(um);



this.addMouseListener(new MouseAdapter(){

public void mousePressed(MouseEvent e)

{

if(e.isPopupTrigger())

{

// At one point I had these calls outside of the inner

class, but moving them

// produced no change.

popupMenu.show((Component)e.getSource(),e.getX(),e.getY

());

}

}

public void mouseReleased(MouseEvent e)

{

if(e.isPopupTrigger())

{

popupMenu.show((Component)e.getSource(),e.getX(),e.getY

());

}

}

});

buildPopup();

}

private void buildPopup() {

popupMenu = new JPopupMenu("UserTree Popup");

cutItem = new JMenuItem("Cut");

popupMenu.add(cutItem);

copyItem = new JMenuItem("Copy");

popupMenu.add(copyItem);

pasteItem = new JMenuItem("Paste");

popupMenu.add(pasteItem);

deleteItem = new JMenuItem("Delete");

popupMenu.add(deleteItem);

this.add(popupMenu);

}

/*

// These are the original eventhandler functions.

public void userTree1_mousePressed(MouseEvent me) {

showPopup(me);

}

public void userTree1_mouseReleased(MouseEvent me) {

showPopup(me);

}

private void showPopup(MouseEvent me) {

if (me.isPopupTrigger()) {

popupMenu.show(me.getComponent(), me.getX(), me.getY());

}

}

*/

}

Sol: 1. Use getSelectionRow() and .isPopupTrigger() together.

2. If me.isPopupTrigger() didn't work, try me.getModifiers()==4.



57. JTree-Custom model-new nodes don't display

I have a JTree with my own model that implements TreeModel. I add a new node to my data structure. At this point I have to notify the treemodellistener of my new addition. However, I don't know how or what could be my treemodellistener. There is an inner class of JTree that is a TreeModelListener that I can't notify. It's protected.

Sol:

protected EventListenerList listenerList = new

EventListenerList();



public void addTreeModelListener(TreeModelListener l) {

listenerList.add(TreeModelListener.class, l);

}

public void removeTreeModelListener(TreeModelListener l) {

listenerList.remove(TreeModelListener.class, l);

}

protected void fireTreeNodesInserted(Object source, Object[]

path,

int[] childIndices,

Object[] children) {

// Guaranteed to return a non-null array

Object[] listeners = listenerList.getListenerList();

TreeModelEvent e = null;

// Process the listeners last to first, notifying

// those that are interested in this event

for (int i = listeners.length-2; i>=0; i-=2) {

if (listeners==TreeModelListener.class) {

// Lazily create the event:

if (e == null)

e = new TreeModelEvent(source, path,

childIndices,

children);

((TreeModelListener)listeners

[i+1]).treeNodesInserted(e);

}

}

}

// This is copied from the default tree model. Sure you must write fire-methods for all events (like in the default model) or you can switch them by an id (like in the fire method of JInternalFrames).

58. JTree Feature

I have a node selected in the Tree which is placed in a panel. If i use RIGHT button of the mouse , is there anyway to find out whether the mouse is clicked on ANY node of the tree or else where in the Tree(means in the blank space ).

Sol: m_tree.addMouseListener( new MouseAdapter(){

Public void mouseReleased(MouseEvent e){

If(e.isPopupTrigger(){

TreePath path = m_tree.getPathForLocation(e.getX(), e.getY());

If(path != null){

M_popup.show(m_tree, e.getX(), e.getY());

}

}

});

59. Problem with Transparent(Non-Opaque) JTree

When I set my JTree to be non-opaque, that is:

JTree myTree;

myTree.setOpaque(false);

((JComponent)myTree.getCellRenderer).setOpaque(false);

the tree itself becomes transparent, and the icon in the TreeCellRenderer becomes transparent, but the text in the TreeCellRenderer remains opaque. How can I make the text transparent as well?

Sol: You must set the non/selectionColor to an opaque color (alpha =1)

myTree.setOpaque(false);

DefaultTreeCellRenderer cr = new DefaultTreeCellRenderer();

Color op = new Color(0,0,0,1);

cr.setBackgroundNonSelectionColor(op);

myTree.setCellRenderer(cr);

Method 2: In YourCellRenderer class:

m_textSelectionColor = UIManager.getColor( "Tree.selectionForground" );

m_textNonSelectionColor = UIManager.getColor( "Tree.textForeground" );

m_bkSelectionColor = UIManager.getColor( "Tree.SelectionBackground" );

m_bkNoSelectionColor = UIManager.getColor( "Tree.textBackground" );

then:

setForeground(select? m_textSelectionColor: m_textNonSelectionColor);

setBackground(select? m_bkSelectionColor: m_bkNonSelectionColor);

60. Re: JTree (swing 1.1) Mouse Clicks - 1 or 2 -

Does anyone know how to specify that a JTree should respond to only one mouse click to open and select nodes in Swing 1.1?

Sol: There is a method called isToogleEvent(MouseEvent) in the BasicTreeUI just overwrite this method to toggle when you want. Or Just add a mouse listener to the Tree. There is a method called getPathForLocation(int x, int y) which you can use to get the treepath and so you can expand and collapse it

public void mousePressed(MouseEvent me) {

toggleExpandState(tree.getPathForLocation(me.getX(),me.getY()));

}

protected void toggleExpandState(TreePath path) {

if (path==null) return;

if(!tree.isExpanded(path)) {

// expand path here

} else {

// collapse path here

}

}

61. HELP - Modifying the size of the JTree cell

If I change the text of one node, and if I refresh the tree by redrawing it, the changed node text is displayed cutted with trailing "...". Does one of you know how to make the JLabel displaying that node change its size to display the entire text correctly ?

I have seen that the UI of the JTree caches the sizes for all the nodes. How can I force it to recompute the size of the JLabel ?

Sol: You can try : myTree.updateUI() after.

Or you make your TreeCellRenderer to override the following method:

public void paintComponent(Graphics g){…}

62. Very important doubt in JTree.? (Deal with multi-roots problem.)

I have one root in JTree.I am putting the root in hidden state for my requirement.And I have 4 roots in JTree. when I give mytree.RootVisible(false).Automattically Root will not be visible.And the Remaining nodes Apple,Banana,pizza,KFC are the roots.How can I handle Apple,Banana,pizza,KFC

seperatly.Suppose I want (4) level under Apple.(when I create new node under Apple)Is it possible?And I want to take whole pizza node elements means child,sub child,leaf under pizza node.

Sol: You can treat each them us multi-roots. In JTree, there are two ways to get the node that you want : path and row. So try the following methods

getSelectionPath/getSelectionRows

getPathForLocation

getPathForRow/getRowForPath…

63. JTree and Tooltips (How to customize and attach Tooltip to a particular leaf and parent in a JTree?)

What I would like is to point on that particular leaf in a tree and the tooltip that would display the representation of data for that leaf. That means that each parent will hava a tooltip with its own name that shows in a tree but each leaf will have the value for that particular leaf and will be different for each of them according to which child the mouse points at. Is that possible??

Sol: override getToolTipText() in JTree:

public class SkopyToolTipTree extends JTree {

public JTree() {

super();

this.setToolTipText(""); //trigger tooltips ON for this object

}

public String getToolTipText(MouseEvent evt) {

if (this.getRowForLocation(evt.getX(), evt.getY()) == -1) return null; //not on a node yet, no tooltip to display...

TreePath curPath = this.getPathForLocation(evt.getX(), evt.getY());

return ((SkopyNode) ((DefaultMutableTreeNode) curPath.getPathComponent (curPath.getPathCount()-1)).getUserObject()).getBalloonText(); //break this up if casting & paren levels too much for you

}

}

64.JTree and converting Object's value

Sol: The name of the node is determined by calling toString() on it. The type name you see Record@1... is just the default toString() showing through.

If it's a DefaultMutableTreeNode that you use, there's a userObject in there to hold your actual type. The DMTN toString() calls the userObject.toString().

Or you can write a TreeCellRenderer that displays the node however you want.

65. MultiLine Text in a JTree

I would like to be able to display paragraphs as a node in a JTree. JLabel does not seem to allow multi-line. How would I go about donig this? Can I add a JTextArea? Do I have to create a TreeRenderer for this?

Sol: you'd create a TreeCellRenderer with JTextArea for this. Make sure you do tree.setRowHeight(0) so it goes to the renderer for its size.

class MultiLineCellRenderer extends JPanel implements TreeCellRenderer {

JLabel icon;

TreeTextArea text;

...

public Dimension getPreferredSize() {

Dimension iconD = icon.getPreferredSize();

Dimension textD = text.getPreferredSize();

int height = iconD.height < textD.height ?

textD.height : iconD.height;

return new Dimension(iconD.width + textD.width, height);

}

...

class TreeTextArea extends JTextArea {

Dimension preferredSize;

TreeTextArea() {

setLineWrap(true);

setWrapStyleWord(true);

setOpaque(true);

}

66. Windows look and feel

I tried the following code. The com.sun.java.swing.JTree didn't give me the required look and feel but the javax.swing.JTree did.

import javax.swing.*;

import java.awt.Dimension;

import java.awt.*;

public class lf

{

public static void main(String args[])

{

try

{

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

System.out.println("set l & f to : " + UIManager.getSystemLookAndFeelClassName());

JFrame jf = new JFrame();

jf.getContentPane().setLayout(new BorderLayout(0,0));

jf.getContentPane().add(new com.sun.java.swing.JTree());

jf.getContentPane().add(new javax.swing.JTree(), "South");

jf.setSize(new Dimension(500,500));

jf.setVisible(true);

}

catch (Exception e)

{

e.printStackTrace();

}

}

}

Sol: The swing package name has changed in JDK 1.2. You need to change your import statement from import com.sun.java.swing.*; to import javax.swing.*;

67. How do I make JTree with my home directories (and not the usual sample JTree)?

Sol: 1. Create a root for your tree;

2. File[] roots = File.listRoots(); which lists the available filesystem roots.( eg. A,C,D disks);

3. add this roots to your tree-root.

68. New kind of Tree / JTree

Each horizontal row can contain more than one node (where as the JTree can only support one). Has anyone seen such a tree implemented using Swing?

Sol: You can only have one TreeNode on a line, but you can use that TreeNode to hold whatever you want. It could hold an array of virtual nodes. You could then use your own TreeCellRenderer to render all the virtual nodes on a single line.

69. Making changes to a selected node in a JTree

I don't know how to programmically change the text of a node in a JTree

Sol: The text of a node is based on the userObject. Try defaultMutableTreeNode.setUserObject().

70. I don't know how to change the color(or the icon) of ONLY the parent of the node that has changed. (Failed a test in this case)

Sol: You can change color or icons by providing your own rendered. In your own TreeCellRenderer, make a decision when to change the node icon.

71. new nodes do not appear in JTree

I've got a JTree that I add nodes to dynamically. No matter what method I call, I can't get the tree to paint the new nodes if the node receiving the new children is expanded. But the weird thing is that if I leave the node receiving children collapsed while I add the new nodes, they appear when I expand it. After it has been expanded once, any new node added will not appear in the tree (I've verified that it exists in the Model, Paths, etc.) regardless of whether I expand, collapse, validate, repaint, resize -- you name it. Oh, and another strange thing -- the JTree was initialized with a DefaultTreeModel that I've added TreeModelListeners to but none of my listeners receive any TreeModelEvents when nodes are added.

Sol: Call treeModel.nodeStructureChanged(node) in order to get the tree to display the new node.

72 make a "program selected" node look like a "mouse selected" node in a JTree

I'm currently using JTree.setSelectionPath(TreePath) to select a given node in my tree. My node is well selected, all nodes are expanded, I can get all data available with

this node ... all seems OK but in fact, there is just one thing that bothers me : the actual node doesn't look "selected" at all.

Sol: One possible reason you misused TreePath constructor.

Check whether you use "new TreePath(my_node)" instead of new TreePath(my_node.getPath()), or other formats.

73 Using a JTable object as a child node in a JTree object

I have a JTree object in which I want to use a JTable object as one of its child nodes. I tried using the JTree constructor with an Object [] as its parameter but this only displays the properties of the object and does not recognize or display it as a table.

Sol: Make a class that implements the TreeCellRenderer interface or subclasses the DefaultTreeCellRenderer class, returning a JScrollPane with your JTable on it as result of the getTreeCellRendererComponent method, when necessary.

Then set the TreeCellRenderer with the appropriate setter method.

74 How do you create a duplicate JTree

To allow a user to edit a JTree and then reset back to the original tree, after having saved the edit changes, I need to maintain a duplicate of the original tree. For info purposes, the JTree is created using the Default Tree Model. What is the best solution and how? I'm attempting to use the Cloneable interface but getting casting errors and I'm not sure of what I'm doing (new to Java).

Sol: Try cloning the treeModel of the tree, because it is the treemodel who contains the data. Another way is to clone the root node of your tree.

75 JTree:setSelectionPath() & TreePath problem HOW?

I've tried to use getTreePath() from TreeModelEvent as a reference for setSelectionPath(...) in JTree But it didn't work.

Sol: TreePath path = new TreePath(currNode.getPath());

tree.makeVisible(path);

tree.setSelectionRow(tree.getRowForPath(path));

tree.scrollPathToVisible(path);

Where currNode is the node you want to select.

76 JTree refreshing

I'm trying to create a JTree by searching through a vector and building a DefaultMutableTree. However, the Vector is empty initially, and gets added to when the program loads from a file. How can I get the JTree to refresh itself and show that it has been changed without going in and rebuilding the entire pane again?

Sol: Reset the TreeModel for the tree object, and then repaint() the tree. This isn't very efficient though as I have to rebuild the tree each time something gets added or changed in my Vector which stores all the information. (I can't find a way to update the tree directly from the Vector without having to create a DefaultMutableTree each time.)

77 DnD/JTree repaint problem within Applet/Browser

I'm supporting an app where a JTree has been subclassed to support DnD. Two of these components are used within a new JFrame created outside of the initial application/applet window. You drag a leaf from one JTree and drop it into the other and the target repaints, displaying the new leaf. This works correctly when run from Visual Cafe as an application but when deployed as an applet and run through a browser, the new leaf does not get displayed after the drop. If you iconize/deiconize the frame, the leaf appears. If you collapse/reopen the parent, the leaf appears.

I've tested this using JRE/plugin 1.3 and this "bug" seems to have been fixed. Unfortunately we use JDK/JRE & plugin 1.2.0 as the standard for our corporate desktops and we won't be moving to 1.3 until much later this year. Ergo, I need a workaround.

Sol: The DnD problem has something to do with the Java Security Manager implementation in some versions of Java Plugin. You may find that a security exception is thrown when a new tree node is added to the tree model. If you can make your applet a trusted applet, maybe the problem will disappear. Hope this helps.

78 Dynamically Changing color of Nodes of a JTree

Sol: You need to extend DefaultTreeCellRenderer.In your getTreeCellRendererComponent() method, first class the super class's method, then

modify the returned Component (a JLabel! And it's actually "this", strangely enough!) as

you see fit. The "value" is passed to this method, which is an instance of your tree

node class. You can get data from your node to make decisions as to how to render it.

Set whatever foreground and backgodund color, font, icon, border, etc., you want, before

returning that Component.

79 How to visually update JTree display (node selection)

Sol: TreeNode[] pathToRoot = m_model.getPathToRoot(startNode);

TreePath thisisit = new TreePath(pathToRoot);

DefaultMutableTreeNode parent = (DefaultMutableTreeNode) startNode.getParent();

m_tree.addSelectionPath(thisisit); // only if you want node selected

m_tree.scrollPathToVisible(thisisit); //expands path and scrolls

// following causes above 'scroll' or 'select' to actually occur, bcome visible, on screen

m_model.nodeChanged( parent );



80. Ordering of Nodes in JTree (database)

Sol: You can use Collections.sort() to order the data.

HashTable treeStuff = <whatever>

List data = new Vector (treeStuff.values());

Collections.sort(data);

JTree tree = new JTree(data);

81 JTree Icon problem

I want to display Icons for the JTree Nodes, I am using Separate class say DemoTreeCellRenderer which extends JLabel & implements TreeCellRenderer Code working fine in appletviewer but On line Browser throws AppletSecurity Exceptions Saying that Access Denied for reading the collasped.gif

code Used:-

ImageIcon collaspedIcon = new ImageIcon("collasped.gif");

What is the right way to display Icon for JTree so that my applet will work fine on Internet explorer Browser or netscape Navigator

Sol: I believe your problem is that the applet is trying to load the image from the hard disk of the host machine and not from the location of your classes. You need to load the image from your codebase. Try this:

URL url;

try

{

url = new URL( (yourApplet).getCodeBase(), filename );

ImageIcon theImage = new ImageIcon(url);

}

catch(MalformedURLException e)

{}

82 How to force visual display of JTree

I'm developing a explorer-like component. I'm having problems with the icons in my JTree component now being displayed correct (open/close icons) in certain situation. Is there anyway to force a visual update of JTree or parts of it?

Sol: try updateUI()

83 Node of JTree in Editmode

Sol: I have a JTree with editable nodes and it works fine with the triple click to start the edit (or the click, pause, click). How can I "force" someone into edit mode programmatically? For example, I also have a menubar and I'd like to add an "Edit" menuitem to it, but I don't know how to throw them into the selected node's cell editor.

Sol: public void actionPerformed(ActionEvent e){

    1. Path = //getSelectionPath

    2. tree.startEditingAtPath(path)

}

84 Refreshing JTree while dragging

I implemented the drag and drop feature in a JTree so the user can drag a node and drop it on another one. As the user drag a node, I would like to highlight the node below the cursor so the user can see on wich node it's gonna be dropped if he releases the mouse button (as in the windows explorer application).

I tried to do it using the method setSelectionPath() in the dragOver() method but the JTree doesn't refresh itself until the user does the drop. How can I make it refresh (repaint() method doesn't work) during the drag?

Sol: Do exactly what you are doing with a CellRenderer. it passes as a parameter the hasFocus flag. using this you can paint the node differently if it has the focus, ie is being dragged over.

85 JTree Root node collapsing his children(refreshing)

I'm using a JTree containing dynamic data. I can add and remove nodes anywhere in the tree with no problem, except for the Root Node.

If I add a child to the Root all the children are collapsed. By tracking what append after the add I saw that the JTree erase his expanded state data and forgot how it was before the refresh.

Sol: see tree refreshing.

86 JTree: Changing Node text?

How I can change the text that a node displays within a JTree?

Right now, the node displays via the toString() command. However, I am creating a JTree which contains a bunch of nodes that display differently depending on the user's choice in a JComboBox (think of it like language selection. If French is selected, the nodes should display via the toFrench() method)

Sol: Change the toString() method of your nodes to return what you want displayed. If you're using DefaultMutableTreeNode, then create a new class that extends it and overrides toString().

87 Selecting a particular node in a JTree automatically

I have an application which uses a JTree. The tree is built based on the data in the database and uses DefaultMutableTreeNode. If the user wants to modify the record(once after the tree has been built and the press of a button), the tree should expand to the node earlier selected. The tree has a root, child1Level, child2Level nodes. I tried through the expandRow(int), but this one expands but to select a node at child2Level, I do not find any method. When I use addSelectionRow(int), it selects in the child1Level nodes, but not in the child2Level nodes. Kindly give me a way to indicate a integer number to reach the child2Level. Or give me a way to build a TreePath from an existing JTree based on the root info (like child1Level, child2Level).

Sol: selectTreePath = new TreePath(treeNode.getPath());

jtree.setSelectionPath(selectTreePath);

jtree.scrollPathToVisible(selectTreePath);

88 How to highlight JTree node without selecting it

I have a JTree in a JApplet. Nodes are expanded dynamically and expanding is rather slow.

Problem: When user clicks a node, program highlights the node _after_ expanding (= after TreeSelectionListener.valueChanged). This means seconds after clicking.

Question: How can I just highlight a JTree node without really selecting it (or do I really have to expand the node delayed, e.g. in another thread)

Sol: Program highlights the node before it calls those mouse and key release adapters.

If to delay the expanding: In TreeSelectionListener you save the event in a private member. In MouseAdapter.mouseReleased and in KeyAdapter.keyReleased

you check if there is an event waiting (in that member). If so, you process the expanding.

89 class for Dynamic JTree?

please let me know which class or method in JTree supports creating JTree structure dynamically from the database.>Thanks in advance.

Sol: there is no direct method to do this. While you can find the loop that will go through all the entries and add nodes so it matches the database. (assuming there is a method to get all children for a parent as an array of DefaultMutableTreeNodes):

void addChildren(DefaultMutableTreeNode nodeCurrent)

{

//get the array of tree nodes, or get the array of objects

//which comprise the children and create

//DefaultMutableTreeNodes of them

DefaultMutableTreeNode[] aChildren = getChildren(nodeCurrent);

for(int i = 0; i < aChildren.length; i++)

{

//get the current child

DefaultMutableTreeNode child = aChildren;

//recursively call this method on the current child

addChildren(child);

//add the child to the current node

nodeCurrent.addChild(child);

}

}

Call this initially with the root node. The children of the root node will be retrieved, then the method will be recalled on each of those children. When a leaf node is hit, the recursion stops. Then the children of each node are added from leaf to root.

90 getDefaultTreeModel() not found in javax.swing.JTree

public void search(JTree t)

{

DefaultTreeModel tml =(DefaultTreeModel)t.getDefaultTreeModel();

DefaultMutableTreeNode temp = new DefaultMutableTreeNode();

int count = tml.getChildCount(temp);

for(int i=0; i<=count-1; i++ ){

DefaultMutableTreeNode test=(DefaultMutableTreeNode)tml.getChild(temp,i);

if(test.getUserObject().equals("balaji_raju")) {

System.out.println("node xxx is on index"+i);

}

}

}

the above code gives the error "no method matching getDefaultTreeModel()found in javax.swing.JTree".

Sol: According to the Javadoc, getDefaultTreeModel is a static method. That means that you have to use "JTree.getDefaultTreeModel()" to call it. Besides, this method is protected,so it can be used by only JTree class or it's subclasses .

91 More freedom with JTree layout

I am currently writing an applet to be used on an administrator's site for a big website. The applet shows the tree structure of the site which is sent to the applet via Serialization from a database. My former version of the sitetree was made in dHTML and had multiple icons for etc. domain pages, page with no access, page that was not currently published, and so on. I decided a while ago that I wanted to experiment with putting the sitetree in an applet but the JTree class does not give me the free layout I desired, for it only allows one set of Icons for each tree, not specified for each node as would be more proper.

Sol: You can use a TreeCellRenderer to do this. Use the TreeCellRenderer to display nodes in different fonts and all the custom settings.

92 JTree adding parent nodes at runtime

Is it possible when using a JTree to be able to added parent nodes to the tree, without having to rebuild the tree. I am using a JTree to visually show the user the list that they are buliding, and require to be able to added parent nodes. So far I have only been able to add child nodes.

Sol: Actually, they're aren't really ANY parent nodes, except for the root node which may or may not be visible.

To simply add a 'parent' node at the end of the rootnode of a JTree called 'myTree' you do something like this:

DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("Parent");

DefaultTreeModel model = (DefaultTreeModel)myTree.getModel();

DefaultMutableTreeNode treeRoot = (DefaultMutableTreeNode)model.getRoot();

model.insertNodeInto(newNode, treeRoot, treeRoot.getChildCount());

The treeRoot.getChildCount() will make sure the node is added at the end of the root node. You can add code to specify the exact position if you want it somewhere else.

93 dynamic JTree not updating

I'm adding nodes to an empty DefaultTreeModel (just a root) attached to a JTree and calling nodesWereInserted() with the path changed and the index of the new node. I attached a TreeModelListener and confirmed that these events are getting through. However, the tree stays empty on the screen.

How do I either:

1) get JTree to change its display when receiving a nodesWereInserted() or

2) if I can't do that, how do I preserve or recreate the expanded node set after nodeStructureChanged() gets called?

Sol: Use treeModel.insertNodeInto(…) is a better way to do this. After using this method, the model will automatically call update method to update the tree.

94 Undo in a JTree

I'm working with a JTree and I'd like to have an undo/redo feature in it. I've been looking at the javax.swing.undo package, especially the StateEditable interface, but it seems to

me this interface demands that I keep a Hashtable list of what changes have been done. I don't like that idea. Instead, I was wondering if it might be a solution to simply put the whole JTree object into a java.lang.Stack each time it changes... ?

Sol: You could certainly do a stack of tree models and pop the stack to achieve undo, but the problem is the amount of storage required to save all those tree models.

What about creating a new tree node class that has undo/redo capability? The user could undo and redo by node and the tree as a whole would have fine-grained undo/redo built-in.

95 Refreshing a JTree

Is there a way to refresh JTree after adding a node (I mean, to make it display the new node), except model's reload() method ? I'd like to aviod using it, since it closes all the nodes.

I'm trying to make a sort of "dynamic" JTree - contents of a node is fetched when the node is expanded for the first time. But after invoking reload() method the node closes again. Do I have to open it "manually" afterwards ?

Sol: The solution I used when doing things like that (with DnD JTrees) are these two lines:

treeDidChange();

updateUI();

Not sure whether the second one is needed, I just put it in to be sure.

96 collapse JTree from within a JMenuBar

I have a JTree and above it a JMenuBar. In the JMenuBar I have an item "close". The purpose is that when somebody selects this item in the MenuBar, the selected node in

the JTree will collapse.

Sol: JTree has a method "collapsePath(TreePath)". That's what you want to call. For TreePath, you need the path from the root to the selected node; that's "new TreePath(node.getPath())",where "node" is your selected node.

97 JSplitPane not behaving correctly on a Sun box

I'm having difficulty with JSplitPane. The left panel and splitter are not shown. Also, the right panel's left 5% isn't shown, meaning that the right panel's contents are either not

adjusted correctly to the panel, or that the right panel is expanding beyond it's container panel, which seems odd.

The GUI looks like a JTree on the left, and a JTable on the right. The JTree and JTable are both added to their respective JPanels. So, there is a JPanel containing the JTree, and another JPanel containing the JTable. Each of these panels are then added to the JSplitPane, the split pane divider's location is set using setDividerLocation(), and the split pane is then added to a master panel. UpdateUI() is then called on the master panel.

Sol: Try using setPreferedSize() on your left component



98 visible tree nodes

Is it possible to know if a node (given by its TreePath for instance) is showing in the visible part of a JTree?

I have a big JTree (14000 nodes) and when I repaint it, it is time comsuming.

That's why I would like to repaint the JTree only if the node that must be visually changed (icon) is visible (the user can see it without scrolling or doing any other action on the frame that contains the JTree)

Sol: What about using

if (myTree.isExpanded(myTreePath)) // this path is expanded and is therefore visible....

I've never used it but it seems like it would work...

By the way, you don't have to repaint a tree. You can use a tree model (DefaultTreeModel) and do this:

myTreeModel.reload(nodeToReload);

99 Basic JTree question

I have a table (Accounts) that has basically two fields that interest me while creating a JTree. They are : AccountNumber and AccountDescription. AccountNumber has the following structure :

1 General

1.1 Administration

1.1.1 Personnel

1.1.2 Cafeteria

1.2 Sales .....

and so goes the structure, which varies a lot, depending on the branch office's size.

How do I create/build a JTree routine so as to have the whole tree built dynamically?

Sol: see the code for details.

100. How to dynamically refresh/update a JTree?

Your tree model needs to call nodeStructureChanged(node), where the parameter "node" is the node that has had children added, removed, changed, or what have you. If your JTree doesn't have a model that is a subclass of DefaultTreeModel, however, you

won't be able to do this. I would try using revalidate(), validate(), or validateTree().. These functions usually refresh.. or a fire*() function can cause a redraw of everything.



101 Changing JTree Content

I used a TreeModel to develop a JTree. I am developing a file browser sort of. Suppose for a win32 system I have a listing of drive in a combo box. By default the browser opens up with the c drive. But when the user user changing the item in combo box suppose from c to d drive, the tree must display the new Files in the d drive. I wrote an action Listener for this, in which I create a new model with this drive name.

But the tree structure does not seem to be changing. Could any one please help with this.

Any type of code regarding this would be useful. I think we must write listener for treeStructure changed or some other listener.

Sol: for refreshing the tree you need to reload() the tree model with the changed node.

For the node insert, you need to model.insertNodeInto(..), Except for the first

node inserted (apart root node), in that case you have to use nodeStructureChanged(rootnode).

102 JTree-Custom model-new nodes don't display

I have a JTree with my own model that implements TreeModel. I add a new node to my data structure. At this point I have to notify the treemodellistener of my new addition. However, I don't know how or what could be my treemodellistener. There is an inner class of JTree that is a TreeModelListener that I can't notify. It's protected.

Sol: I suggest this should work:

protected EventListenerList listenerList = new

EventListenerList();



public void addTreeModelListener(TreeModelListener l) {

listenerList.add(TreeModelListener.class, l);

}

public void removeTreeModelListener(TreeModelListener l) {

listenerList.remove(TreeModelListener.class, l);

}

protected void fireTreeNodesInserted(Object source, Object[]

path,

int[] childIndices,

Object[] children) {

// Guaranteed to return a non-null array

Object[] listeners = listenerList.getListenerList();

TreeModelEvent e = null;

// Process the listeners last to first, notifying

// those that are interested in this event

for (int i = listeners.length-2; i>=0; i-=2) {

if (listeners==TreeModelListener.class) {

// Lazily create the event:

if (e == null)

e = new TreeModelEvent(source, path,

childIndices,

children);

((TreeModelListener)listeners

[i+1]).treeNodesInserted(e);

}

}

}



This is copied from the default tree model. Sure you must write

fire-methods for all events (like in the default model) or you

can switch them by an id (like in the fire method of

JInternalFrames).

103 Nodes order in JTree .. how to ?

I am using JTree by sending my data base results as hashtable of hashtables. I am not able to get the display in the alphabetical order in the display.My search results are sorted by alphabet order.

Sol: You need a node class that sorts its children as they are added. Also, the objects you put into the node must implement Comparable, as String does. See code.

104 JTree Feature

I have some specific requirement in JTree. I have a node selected in the Tree which is placed in a panel. If i use RIGHT button of the mouse , is there anyway to find out whether the mouse is clicked on ANY node of the tree or else where in the Tree(means in the blank space ).

Sol: see code.



Summary.doc

105(1) Need two or more jtree views of a single tree model, when adding/collapsing happens, all the views should have change their appearance. How to do it?

Sol: Add TreeModelListener to listen to the primary tree, so that they can stay in synch.

106(2) I want to differentiate two types of defaultMutuableTreeNode, such as different color or icons. How to do it?

Sol: create your own TreeCellRenderer extends DefaultTreeCellRenderer, overiding the following method:

Public Component getTreeCellRendererComponent(……){

Label comp = (Label) super.getTreeCellRendererComponent(…);

comp.setForeground(Color.red);

comp.setIcon(icon);

return comp;

}

Jtree.setCellRenderer();

107(3) The actual expanded state of tree should be restored after refreshing, how to do it?

Sol: DefaultTreeModel.insertNodeInto() and

DefaultTreeModel.removeNodeFromParent(); And get the DefaultTreeModel using Jtree.getModel(); This allows you update the tree without reloading it.

108(4). Can I use drag-and-drop with a JTree?
Apparently not at this time: bug 4165577 (http://developer.javasoft.com/developer/bugParade/bugs/4165577.html) in the JDC bug database reports problems with this combination.

109(5). How can I select the last child of the root? I don’t know how to find the path.

Sol:

Create the path by yourself:

TreeModel theModel = myTree.getModel();

Object root = theModel.getRoot();

int childCount = theModel.getChildCount(root);

Object lastChild = theModel.getChild(root, childCount-1);

TreePath thePath = new TreePath( new Object[2] ({root, lastChild}));

110(6). Render the tree nodes by my own wish: put custom icons for the custom nodes.

Sol: write your own TreeCellRenderer extends Jlabel.

  1. Question.doc

111(1). Can I use drag-and-drop with a JTree?
Sol: Apparently not at this time: bug 4165577 (http://developer.javasoft.com/developer/bugParade/bugs/4165577.html) in the JDC bug database reports problems with this combination.

112(2). Why is my JList/JTree component sized improperly when I add/remove items from the Model?
Sol: While there could be many reasons for this behavior, one possibility is that you have a JScrollPane in a GridBagLayout without a minimum size set. Try setting a reasonable value and see if your problem disappears. <Brian Sletten>

113(3). How do I put my information into a tree?
Sol: Use a DefaultMutableTreeNode. Use setUserObject() to include your information in the node. Make sure yourObject.toString() displays the information for your node (unless you are willing to implement a custom TreeCellRenderer).

114(4). How can I get different icons for my tree nodes?
Sol: The look-and-feel is usually responsible for providing the icons in a tree. To draw your own icons for a node, implement and install a custom TreeCellRenderer.

115(5). How do I load nodes on demand?
Sol: Make a subclass of DefaultMutableTreeNode. Override getAllowsChildren() and getChildCount() to load the tree beneath each node the first time those methods are called.

116(6). Why won't my folder/directory/etc. TreeNodes draw properly when they don't have any children?
Sol: Set allowsChildren to be true for all of your container nodes, and askAllowsChildren to true in the TreeModel. By default, askAllowsChildren is false, which makes the model call isLeaf() to decide how to render a node. The isLeaf() method returns true if the node doesn't have any children at the moment. So, by default all childless nodes are drawn as leaves regardless of whether they could have children.

117(7). How do I expand or collapse all tree nodes?
Sol: JTree does not have a method to do this directly. You can expand the whole tree like this:

    int row = 0;
    while (row < tree.getRowCount()) {
        tree.expandRow(row);
        row++;
    }

or collapse it like this:

    int row = tree.getRowCount() - 1;
    while (row >= 0) {
        tree.collapseRow(row);
        row--;
    }

118(8). How can I automatically start editing a TreeNode, for example a new node that the user has added?

Sol: It's easy with DefaultMutableTreeNodes and a DefaultTreeModel model:

DefaultMutableTreeNode newNode = ...
model.insertNodeInto(parentNode, newNode, 0); // or whatever position
TreePath path = new TreePath(newNode.getPath());
tree.expandPath(new TreePath(parent.getPath()));
tree.setSelectionPath(path);
tree.startEditingAtPath(path);



searchSummary.doc

119(1). Want to start with the tree expanded completely.

Sol: JTree does not have a method to do this directly. You can make it this way:

Row = 0;

While( row < tree.getRowCount())

{

tree.expandRow(row);

row++;

}

120(2). Querying data from a hashTable to build a tree, want the tree with ascending order.

HashTable treeStuff = <whatever>

List data = new Vector (treeStuff.values());

Collection.sort(data);

JTree tree = new JTree(data);

121(3). Want to paint my own handle that is attached with a node in a JTree. Motif L&F currently is being used.

Sol: With Metal L&F, rewrite TreeCellRender. Extending Jlabel and implementing TreeCellRenderer I can manipulate the icon any way you want.

For a universal way to solve it (for Motif, Metal and Windows), you can change it from UI.

JTree tree = new JTree(model);

ComponentUI treeUI = tree.getUI();

If(treeUI istanceof BasicTreeUI)

{

((BasicTreeUI) treeUI).setExpandedIcon(new ImageIcon("expand.gif"));

((BasicTreeUI) treeUI).setCollapsedIcon(new ImageIcon("collapse.gif"));

}

P.S: ComponentUIà TreeUIà BasicTreeUI, namely, superclass to subclass relation.

Comments: To write the sentence: ComponentUI treeUI = tree.getUI();

If(treeUI instanceof BasicTreeUI) {….}

A clear understanding of the hierarchy and detail in each component is necessary, which is time-consuming.

122(4). How to find a specific node (with user object in String) in a tree in order to insert a string to its children?

Sol: Use getNextNode method in DefaultMutableTreeNode to match the string you want to find.

123(5). Two panels, some nodes in a tree is displayed in panel A, panel B is to display the relative part of the tree when a node is selected. When selecting B after A in panel A, the tree in panel B is not refreshed.

Sol: Updating the state of component should only occur within the event dispatching thread. So:

Thread runner = new Thread(){

public void run(){

if (somethingHappened){

Runnable runnable = new Runnable(){

public void run(){

model.reload();

}

}

SwingUtilities.invokeLater();

}

}

}

runner.start();

124(6). When updating, only display half menu and half tree, why?

Sol: Updating the state of component is not thread safe. DefaultMutableTreeNode is not thread safe actually. A good convention to adopt is synchronizing the root node of the tree.

125(7). How to create a Jtree whose node information is fetched from a database?

Sol: create a class which extends DefaultMutableTreeNode. Add all the information to the relative nodes (including parents and children). Then add them to the DefaultTreeModelà JTree tree = new JTree (treeModel). Set Editable, RootHandle, and path afterwards.

126(8). Want to create a Jtree with mutliple root nodes. And use my own FileTreeNode which extending DefaultMutableTreeNode rather than DefaultMutableTreeNode itself.

Sol: Construct the tree with an empty DefaultMutableTreeNode and setRootVisible(false). Then add the customized FileTreeNode to the roots.

127(9). For a large tree, how to remove/clear all the nodes except the root?

Sol: method A: root.removeAllChildren(), while I don’t know whether it is ecnomical.

B: create an empty implementation of TreeModel interface and set your tree’s model to that empty implementation.

128(10).When traversing down a tree and hitting a Label that goes out of the viewpoint, it auto-scrolls horizontally to make the Label viewed as fully as possible. How to stop this and make it initialized by the user?

Sol: Create a class which extending the Jtree and override the scrollRectToVisible method. Then make a new object with this class and setScrolltoExpand false.

Public class XMLTree extends JTree{

Public XMLTree(TreeNode value){

Super(value);

}

public scrollRectToVisible(Rectangle aRect){

aRect.x=0;

super.scrollRectToVisible(aRect);

}

…….

………..

}

XMLTree newTree = new XMLTree(node);

newTree.setScrollToExpand(false);

129(11). After adding nodes to the current node in JTree, I want to change the current selection to one of its children, but I can’t make it.

Sol: do the following things will help:

treeModel.fireTreeNodeInserted(…);

treeModel.fireTreeStructureChanged(…);

// These two help to make the newly added nodes visible in the JTree.

tree.setSelectionRow(row);

tree.expandPath(NEW PATH);

tree.makeVisible(NEW PATH);

tree.scrollPathToVisible(NEW PATH);

tree.setSelectionPath(NEW PATH);

130(12). Don’t want to make the node changeable.

Sol:

DefaultMutableTreeNode top = new DefaultMutableTreeNode();

DefaultTreeModel tModel = new DefaultTreeModel(top);

JTree tree = new JTree(tModel);

tree.setEditable(false);

131(13). Different Nodes with different icons. (custom nodes, custom icons)

Sol: Write your own TreeCellRenderer extends JLabel. And override the method getTreeCellRendererComponent.

132(14). When the node is at the end of the tree window, collapsing it causes the scroll up to the tree root node. I am using JBuilder 2.0, with Swing 1.0.1.

Sol: This problem does not exist in Swing 1.3. Many parts have been refined through the updating of Swing version.

133(15). In a Jtree How do I get the node that is currently single-clicked?

Sol: The method getSelectionPath().this returns the TreePath for the currently selected node.

134(16). How can I make sure that only one node can be single-clicked every time?

Sol: TreeName.getSelectionModel().setSelectionMode

(TreeSelectionModel.SINGLE_TREE_SELECTION);

135(17). How do I listen to the event changed by the clicking on the tree node?

Sol: For the node selection changes, you need to add a listener for that purpose:

tree.addTreeSelectionListener(new TreeSelectionListener()

{

public void valueChanged(TreeSelectionEvent e)

{

DefaultMutableTreeNode node = (DefaultMutableTreeNode)

}// value changed

});// TreeSelectionListener

136(18). Is it possible to use different icons for different sets of leaves in a single JTree?

Sol: Create your own TreeCellRenderer extends DefaultTreeCellRenderer, which extends JLabel, and override the method getTreeCellRendererComponent.

137(19). Refreshing of JTree after updating (refresh or update tree)?

Sol: Using DefaultTreeModel to add or remove the nodes is easier:

DefaultTreeModel.insertNodeInto() // add

DefaultTreeModel.removeNodeFromParent(); // remove

**: Update the tree without reloading it.

rootNode.removeAllcChildren();

DefaultTreeModel.reload(); // use both to remove.

JTree.getModel(); //get the DefaultTreeModel

138(20). How to traverse a JTree which contains jpeg/gif links and display the images in a separate panel?

Sol: Method 1:

Add JLabel to JPanel, JPanel to JFrame and then set the JLabel's icon using:

Icon im = new ImageIcon("SomeFile.jpg");

jLabel.setIcon(im);

Finally call jFrame.pack() to resize to the image.

Method 2: add to your [separate] panel JEditorPane

JEditorPane srcImagePane = new JEditorPane();

srcImagePane.setContentType ("text/html");

srcImagePane.setEditable (false);

srcImagePane.setText("<img src="yourImage.[gif/jpg]">");

panel.add(srcImagePane);

on "setText(String)" you can add ANY html parameter you need just like you doing that in regular html file such as border=someValue, additional string as an imageName and so on...

139(21). how to rename a node in JTree with the pop up menu?

Sol: If you using the editor for the tree just for renaming, you only must call

tree.startEditingAtPath(/* path of selected node*/);

which Selects the node identified by the specified path and initiates editing. The edit-attempt fails if the CellEditor does not allow editing for the specified item.

Otherwise you must show a dialog with an entry field for the name, set the name to the node and repaint the tree...

140(22). JTree with JScrollPane and JSplitPane problem:

I have a jTree wrapped in a jScrollPane and it makes up the left component of a JSplitPane. The problem is that I don't see the vertical and horizontal scrollbars. I have made the splitpane enabled (for now) just so I can check to see if the scrollbars are visible, which they are. But if I move the splitpane over the Jtree the scrollbars become hidden.

Sol: (I am using JDK1.3):

//*****tree is a JTree****

//*****panel is a JPanel which is added to the right side of the JSplitPane

//this would paint the scrollbars automatically as needed

//JScrollPane scrollPane = new JScrollPane(tree);

//*****this is what you have, which always draws scrollbars

JScrollPane scrollPane = new

JScrollPane(tree,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPan

e.HORIZONTAL_SCROLLBAR_ALWAYS);

JSplitPane innerPane = new

JSplitPane(JSplitPane.HORIZONTAL_SPLIT,scrollPane, panel);

innerPane.setContinuousLayout(true);

innerPane.setOneTouchExpandable(true);

Then I would add the innerPane to a JPanel or a JFrame.

P.S.: 1. from http://java.sun.com/docs/books/tutorial/uiswing/components/splitpane.html,

It is suggested that we’d better put the component of interest into a scroll pane, then put a scroll pane into a splitPane.

2. JsplitPane.setContinuousLayout(): Sets whether or not the child components are continuously redisplayed and layed out during user intervention

141(23). Jtree. Add a Node

I try to add a node to a JTree (using DefaultTreeModel.insertNodeInto). But if I do this when I have already open the subtree (in whitch I add the new node), It doesn't appear but it's created. If I do this when I haven't already open the subtree, It appear.

Sol: Method 1: Add the node as you did, next, get your tree's model (getDefaultTreeModel()) and call nodesWereInserted(TreeNode node, int[] childIndices)

Method 2: the best could be to call insertNodeInto(MutableTreeNode

newChild, MutableTreeNode parent, int index) from your DefaultTreeModel

(javadoc) : "Invoked this to insert newChild at location index in parents children. This will then message nodesWereInserted to create the appropriate event. This is the preferred way to add children as it will create the appropriate event."

DefaultTreeModel.nodesWereInserted: Invoke this method after you've inserted some TreeNodes into node.

142(24). How do you get the newly added node in a JTree?? and how do you

refresh the view of new tree along with the newly added node? (update, repaint)

Sol: Method 1.You have to use DefaultMutableTreeNodes and a DefaultTreeModel

model:

DefaultMutableTreeNode newNode = ...

// or whatever position

model.insertNodeInto(parentNode, newNode, 0);

TreePath path = new TreePath(newNode.getPath());

tree.expandPath(new TreePath(parent.getPath()));

tree.setSelectionPath(path);

tree.startEditingAtPath(path);

Method 2.If your tree model is a subclass of javax.swing.tree.DefaultTreeModel

it is just a matter of calling

((DefaultTreeModel)yourTree.getModel()).reload();

143(25). In JTree,how to set the pop-up menu to node

Sol: Use DefaultTreeModel, DefaultMutableTreeNode, JTree,

tree.add(jPopupMenu);

tree.addMouseListener(this){

public void mouseReleased(MouseEvent e){

jPopupMenu.show(tree.getX(),e.getY());

}

144(*26). How to set Root Node selected for JTree

I want set tree root node selected after I create new a Jtree?

Sol: (you have to have a selection model for that tree)

TreePath path = tree.getPathForRow(0);

selectionModel.setSelectionPath(path);

Method 2: try this:

setSelectionRow(0) and setSelectionPath(new TreePath

(rootnode.getUserObjectPath()))

OR: JTree.getModel().getRoot() or setRoot()

145(*27). Building a JTree from a database

I'm attemting to build a Jtree with entries from a database. Each entry knows the id of their parent, so I can easily get an array of all the children at a particular node. My problem is finding the loop that will go through all the entries and add nodes so it matches the database. Does anyone know what kind of loop I need to achieve this?

Sol: (assuming there is a method to get all children for a parent as an array of DefaultMutableTreeNodes):

void addChildren(DefaultMutableTreeNode nodeCurrent)

{

//get the array of tree nodes, or get the array of objects

//which comprise the children and create

//DefaultMutableTreeNodes of them

DefaultMutableTreeNode[] aChildren = getChildren(nodeCurrent);

for(int i = 0; i < aChildren.length; i++)

{

//get the current child

DefaultMutableTreeNode child = aChildren;

//recursively call this method on the current child

addChildren(child);

//add the child to the current node

nodeCurrent.addChild(child);

}

}

Call this initially with the root node. The children of the root node will be retrieved, then the method will be recalled on each of those children. When a leaf node is hit, the recursion stops. Then the children of each node are added from leaf to root. This

should be all you need.

146(28). Changing image of a leaf node in JTree
i would like to set green color to the image of the node which is by Default a dark circle. ie i would like to to green when displayed now when i select the node(leaf) and click on Disable the image should change to red.

Sol: Write your own TreeCellRenderer, which sets the icon to red or green based on the state of the node's Object. Creating a subclass of DefaultTreeCellRenderer and overriding the getTreeCellRendererComponent method. Because DefaultTreeCellRenderer is a subclass of JLabel, you can use any JLabel method -- such as setIcon -- to customize the

DefaultTreeCellRenderer.

147. repainting a JTree

In my application I have to dynamically replace a tree (JTree) as per the user selection. That is, if a tree is existing and displayed in the GUI, it is to be replaced with another tree as the user selects.

Currenlty I'm replacing the existing tree object with the new one but the new tree is not displayed and the tree selection is disabled. My code is as below:

//initial loading of the tree and works fine

DefaultTreeModel treeModel ;

tree = (JTree) getTree();

tree.addTreeSelectionListener(myTreeSelectionListener);

tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);

treeModel = (DefaultTreeModel) tree.getModel();

treeModel.reload();

//now I wnat to replace it with another tree

tree = getNewTree();

treeModel = (DefaultTreeModel) tree.getModel();

treeModel.reload();

Sol: I feel some thing is missing in your code.. Where did you add the new tree to component ? i guess when you create you add it to the component.

cuz i dont know the parent of tree(according to available code), i assume it to be JScrollPane. to change the new tree,

JViewport c = (JViewport)tree.getParent();

tree = getNewTree();

treeModel = (DefaultTreeModel) tree.getModel();

c.setView(tree);

148 Swing JTree Images (customized nodes)

I need to customise the JTree nodes based on the type of the node and using my own cell renderer. So I was looking for swing's default images for folder(opened,closed) adn leaf images.

Sol: If you simply want to chage the node images you can use this:

ImageIcon oicon = new ImageIcon("open.gif");//youropen

ImageIcon cicon = new ImageIcon("closed.gif");//yourclose

ImageIcon bicon = new ImageIcon("bullet.gif");//yourbullet

//UIManager.put("Tree.leafIcon", icon);

UIManager.put("Tree.openIcon", oicon);

UIManager.put("Tree.closedIcon", cicon);

UIManager.put("Tree.leafIcon", bicon);

149 more JTree help

I'm trying to do 2 things and any help would be greatly appreciated. I have a JTree in my form with some buttons at the bottom of the form. The buttons become active once the user selects a node in the tree. When the user clicks on one of the buttons I need to to the following (the tree is 3 levels deep - root, root's children, leaves):

1) If the selected node is a leaf then I need to find the index of this leaf in it's parent's tree and then I need to find the index of the leaf's parent in the root node's tree.

2) If the node is not the root node and the node is not a leaf (2nd level) I need to find the index of this node in the root node's tree.

I know I need to put some code in the void btnEdit_actionPerformed(ActionEvent e) method and I've also set up the button listener. I've been trying for days to figure this out and haven't been able to.

Sol: 1. Get the selected node (use the JTree.getSelectionPath() method, then use the getLastPathComponent() method on the TreePath that you get)

2. Cast the selected node to a DefaultMutableTreeNode. This class is what JTree actually uses to store nodes, and gives you lots of convenience methods.

3.Use the DefaultMutableTreeNode's getIndex() method

150 How to set a particular node selected in a JTree from within the model

I have an adapter class that provides communication between my JTree and data model. My adapter class implements TreeModel, TreeExpansionListener, TreeSelectionListener and a listener for changes to my data model.

My data model keeps reference to the currently selected node. It is working quite nicely when I select a tree node with the mouse (the data model is updated accordingly with the node selected), however my problem occurs trying to go the other way (set the selected node in my data model and have it reflected in the tree).

I know that my selection in the tree is changing correctly as when the selection changes it fires off an event to update the attributes window associated with the currently selected node. I just can't get the node to become highlighted.

Sol: Does your model really have to keep track of the selected item or can the two views (the JTree and the attributes window) not be coupled together in the user interface instead?

Failing that, you could always consider implementing TreeSelectionModel as well and calling JTree.setSelectionModel since you're keeping track of the tree selection for it already. This is quite a bit of work though.

If that's too much trouble then if you can work out the TreePath for the node that's been programmatically selected through your model then you could use JTree.getSelectionModel().setSelectionPath. Have a look at tree.getSelectionModel().setSelectedPath(new TreePath(selectedObject)).

This approach is a bit warped, though, since it implies that your model knows about the view and therefore couples them together.

151 Double clicking JTree leaf

I would like to trigger an event after double clicking the leaf node of a JTree. I use TreeSelectionListener to detect the events but how to extend this to determine double clicking?

Sol: double-click is a MouseEvent so you will need to add a MouseListener to your JTree. Inside the method mouseClicked(MouseEvent e) of the mouse listener you will check for a double click with the following mouse event method

if (e.getClickCount() == 2)

{

// some action

}

If the 'some action' you want to drive is also available to the user through a JMenuItem or a JButton you can initiate the event through jmenuitem.doClick(). A method inherited from AbstractButton.

152 How to display a JTree expanding DOWN ???

I would like to create a JTree which expands down instead of to

the right.

Is this possible/easy to do, what should I override ?

Sol: Try this:

myJTree = new JTree(myTreeRoot);

MetalTreeUI myJTreeUI = new MetalTreeUI();

myJTree.setUI((TreeUI)(myJTreeUI));

myJTreeUI.setRightChildIndent(0);

myJTreeUI.setLeftChildIndent(0);

myJTree.putClientProperty("JTree.lineStyle", "None");

myJTree.putClientProperty("Tree.hash", new ColorUIResource

(Color.white));

153 Alternate visualizations for JTree

I'm looking for an alternate visualizations of JTree, besides the usual vertical-trunk + horizontal branches

E.g.,

(1) Branches that split out diagonally down-and-left and down-and-right.

(2) Sideways (Horiz trunk + vertical branches)

(3) Upside-down

(4) Trunk on the right of the panel rather than the left.

(5) A tree displayed as a parenthesized parsed expression thus:

(Sol (Earth (Luna), Jupiter(Io,Europa,Ganymede,Callisto), Mars(Phobos,Deimos)))

Sol:

import javax.swing.*;

import javax.swing.tree.*;

import java.util.*;

public class AlternativeView {

public static void recursive(StringBuffer s, Object node) {

if (node == null) return;

s.append(node);

if (!(node instanceof TreeNode)) return;

TreeNode n = (TreeNode) node;

if (n.isLeaf()) return;

s.append("(");

boolean first = true;

for (Enumeration e = n.children(); e.hasMoreElements(); ) {

if (!first) s.append(",");

recursive(s, e.nextElement());

first = false;

}

s.append(")");

}

public static String parseTree(JTree tree) {

if (tree == null) return null;

StringBuffer s = new StringBuffer();

recursive(s, tree.getModel().getRoot());

return s.toString();

}

public static void main(String[] args) {

JTree tree = new JTree();

System.out.println(parseTree(tree));

}

}



154 Custom JTree icons

I'd like to create my own JTree icons. Where are the existing icons for expanded/collapsed nodes (the lever that either points to the right or points down), and where is the blue folder used for non-leaf nodes? Are these copyrighted?.....meaning can I take them, make a minor change to the icon, and use them?

155 How to get rid of handlers in JTree

I'd like to get rid of JTree's handlers. It's very easy to get rid of them in root level but I'd like to get all of them off. I have made my own listeners and don't need them.

If you could also tell how to change the look of them? I could then change them to 0x0 pixels image.

TreeCellRenderer doesn't allow any access to handlers. How do I access that?

156 JTree display after update

I see several references to problems of this type already; the answers to them did me no good.

I t seems so simple - I add a node (with java code - no mouse involved - ( and it is there; I can 'read' and 'print' its inner values and path.)

But the JTree (in a JPanel) will not expand the parent to show the new nodes no matter what I try.

I have tried all the following on all the nodes from the root to the parent I added to, nothing produces a tree display updae:

(sofar is a TreePath)

//m_tree.setExpandedState(sofar, true);//tyhis won't even compile

m_tree.expandPath(sofar);

m_tree.addSelectionPath(sofar);

m_tree.makeVisible(sofar);

m_tree.scrollPathToVisible(sofar);

m_tree.fireTreeExpanded(sofar);

m_model.reload(localNode);

((DefaultTreeModel)m_tree.getModel()).nodeStructureChanged(startNode);

What the heck do you need to do to make the tree redraw? It souldn't be this hard.

I saw one reference to firenode ... but don't have any clear sense of how to generate all the parameters for that method.

Sol: method 1:

Try adding your JTree to a JScrollPane which is added to your JPanel. Assumptions:

- sofar is the TreePath to the node just added.

- your JTree is single select

jtree.setSelectionPath(sofar);

jtree.scrollPathToVisible(sofar);

If the parent node of the node represented by sofar is already expanded, then the above will work. If the parent node is not expanded, then your node just added may not be visible, but it will be selected.

Method 2:

model_.nodeStructureChanged(parent); //this will collapse the tree to the parent

tree_.expandPath(new TreePath(parent.getPath())); // this will expand up to the parent

tree_.expandPath(new TreePath(child.getPath())); // this will expand up to the child.

Things to be aware of:

1) Make sure you are adding the node on the gui thread.

2) Make sure that it is in a scroll pane, else you won't see the full tree

3) Make sure the model you are calling nodeStructureChanged is the one your tree uses.

157 JTREE leaf nodes problem

I'm making a JTree displaying files and dirrctories.

I use the default treecellrenderer because it's already displaying dirs and files icons. When displaying a directory, the icon is generally correct because a dir usually contains childrens files or dirs. So defaultClosedIcon is set.

I've got a problem with empty dir because they've no child.

My quetsion is : how can I set a particular node NOT leaf (as if it had children) even if it is a leaf node in my JTree ?

I tried the setAllowChildren (true) method, but it does not change the L&F.

I also tried using a personnal TreeCellRenderer, but I don't want to change all leaf nodes's appearance, just a few of them (dir but not files). I can't identify a particular node with TreeCellRenderer...

158 JTree...why?

Can someone give me a real life example of when you might use a JTree, other than a corporate layout?

Sol:

Sure - file systems, www histories, categorical listing of settings.. basically anything that can be broken down into categories!

Ask again:

Understood, but that is where JTrees are currently used. How about something in the corporate arena...where you might be writing something to display in a JTree that is not Sol:

I use a JTree to display Sibley and Monroe's taxonomy of the Class Aves (that's Birds). It's divided into 22 orders, which are subdivided into 146 families, which are in turn subdivided into 9702 species. Not corporate enough? Okay, at work the items we sell are classified into 11 commodities, which are subdivided into about 200 subcommodities, containing about 40000 items at the lowest level.

159 JTree GUI Orientation

I am on a team where we are trying to create a dynamic "Root Cause Analysis Tree" which looks like a typical class hierachical diagram; however, JTree makes everything look like FileExplorer. Does JTRee have some way to rotate the orientation so that the root is at the top-center of

the panel and everything is added beneath (left to right)?

ROOT

*

*

******************************************

* * * *

* * * *

CHILD CHILD CHILD CHILD

160 Populating JTree with objects rather than strings

I would like to populate a JTree with objects; upto now I have been using a string from the object, as all the examples show how to do, but I need to call functions from that object. I still need the string to appear on the treenode naturally.

I have found no examples that do this through the several books that I have purused. The DefaultMutableTreeNode only takes an object. I could extend my own version of it, but not sure how to get the tree to display the naming strings.

161 JTree does not display software selection

Author: holtsch Jun 26, 2000 4:10 AM

I have a JTree to which the user can add nodes. A new node should be automatically selected - but that seems to not work with the following code:

<pre>

// get the path to the selected node (it has been added before)

TreePath path = jTree.getSelectionPath();

TreeModelEvent event = new TreeModelEvent(this, path);

// model.fireTreeNodesInserted(event); // this does not work! why?

model.fireTreeStructureChanged(event);

// <em>node</em> is the parent node of the new node

path = path.pathByAddingChild(node.child(node.getChildCount()-1));

jTree.expandPath(path); // this seems to have no effect :-(

// jTree.clearSelection();

jTree.addSelectionPath(path);

</pre>

With this code, the right TreeSelectionEvent is sent and my new node is displayed correctly in a details window. Also, when I add a further node, that works correctly (it is appended to the previously created node). However, the selection should also be displayed in the tree - just like it is when the user clicks on a node. And that does not work.

162. ToolTipText on JTree nodes

I wonder if anyone has successfully set "ToolTipTexts" on JTree nodes. I need to do it. I have defined a custom renderer and called "setToolTipText(String tip)" from within the getTreeCellRendererComponent method. My code compiles all right but no ToolTipTexts are set on my tree nodes. Any sample code would be appreciated.

Sol: Did you register your tree with the tooltipmanager to display tooltips.

//...where the tree is initialized:

//Enable tool tips.

ToolTipManager.sharedInstance().registerComponent(tree);

163 child nodes displayed in right side of pane when node is selected...how do you do this?

I have a JTree which is contained in the left side of a split pane. I want the child nodes to be displayed on the right side of the split pane when a node is selected. I do not need help

in figuring out how to get the child nodes of the selected node-- I have this done. My problem is this: How do I display the child nodes in the right pane? I have the nodes stored in a class IconNode which allows me to retrieve the icon and the

string easily. I've tried placing them in a label and adding the label to a list in the right side of the scroll pane but the labels are added on top of each other (if there's more than one child node to display). Does anyone know what type of swing component I should use to display the child nodes? How do you normally do it--I can't find any examples on this...

164 spacing between two nodes in JTree

how to increase the vertical distance between tow nodes in JTree?

Sol: Use the JTree's method setRowHeight(int rowHeight) where rowHeight is the height of each cell in pixels.

JTree testTree = new JTree();

testTree.setRowHeight(20);

results in 20 pixels between two nodes

165 Alphabetical JTree Node insertion

Is there any easy way to insert a node alphabetically within a JTree branch or JList alphabetically? I will have to write the algorithm otherwise (which I'd rather not).



166 Adding scrolling to JTree - please help

I add a JTree in a panel with no scrolling when the tree is very large…

Sol: add the tree into a scrollpane first , then add the scrollpanel to the panel.

167 JTree & setForegroundColor of special Leafs

i'm using a JTree to display tech-data. when i click on a leaf

with my right mousebutton a popupmenu splashs up and then i can

set the status of this leaf. on the one hand i can give it the

status "opened" (then the foregroundcolor of this leaf should be

black) and on the other hand there's the status "closed" (the

foregroundcolor should be red).

i can specify the color which is displayed when the leaf has the

focus (in the TreeCellRenderer) but the color of the leaf should

remain so long until i change status. I am not able to modify

the foregroundcolor for each Leaf by a method (this woulf be the

method in the popupmenu).

Sol: All visual aspects of a tree node are determined by the TreeCellRenderer.

Subclass from DefaultTreeCellRenderer, and overwrite

public Component getTreeCellRendererComponent(JTree tree, Object

value, boolean sel, boolean expanded, boolean leaf, int row,

boolean hasFocus) {

Component c = super.getTreeCellRendererComponent(tree,

value, sel, expanded, leaf, row, hasFocus);

if (value instanceof MyObject) {

MyObject mo = (MyObject) value;

if (value.someState()) {

c.setBackground(Color.black);

}

}

}

The value is your object. You can cast it and ask for its

properties. Based on the properties you simply set the the

foreground color or background color.

Don't forget to install your renderer:

JTree tree = new JTree();

tree.setCellRenderer(new MyTreeCellRenderer());

168 Urgent-Search for a node in JTree...

I've created a JTree(DefaultMutableTreeNode) and I need to search for a particular node(which Iam entering as a String object) in that tree. How can I retrieve that particular node.

169 JTree/JCombo ( customized node)

I am building a JTree for a Hirechy in my HR System. What i

noticed was theat the JTRee or the JcomboBox do not have a

method in which i can display some value but the Value which

will be stored will be diffrent.

Those how are familiar with D2K may know that a Combo Box can

have a display Value and a Item Value. The item Value will be

stored in the Database. This is something similar to HasTables

in Java.

Is there any way thru which i can get this kind of a functionality.

Sol: Using renderer delegates for your JComboBox and JTree

implementations will allow you to interpret the underlying data

in any way you wish. The data element for all of the 'Swing'

model types is <Object>, which implies that data can be of any

non-primitive type.

In the renderer interface, this 'opaque' value is passed into

the method that returns the instance of the renderer for a

particular 'cell'. In this code you can interpret and display

this <Object> in any way you like. There are good examples of

how to use renderers on Sun's JDC site and in any decent Swing

book.

170 JTree -Limitation

Author: djeouaille Jan 25, 2001 9:50 PM

Is there another Tree implementation that allows customization.

I want to create a JTree that will display it nodes horizontally:

---------- CHILD 1

|

|

FATHER ---------------- CHILD 2

|

|

---------- CHILD 3



Is there a possibility?

Djeouaille

JTree -Limitation

Author: mitchg Jan 26, 2001 5:30 AM

Sol: Not really. The information you are looking to display is different from the information in the <TreeModel> and <TreeNode> classes. I suppose that you could re-write the UI delegate for <JTree>, but that seems like a pretty difficult task.

There is an AWT example program that shipped with past versions of JDK that had an example for a tree-oriented layout that supported weighted graph relationships...that might be an easier solution than trying to beat <JTree> into something radically different.

Mitch Goldstein

Author, Hardcore JFC

(SIGS/Cambridge, Feb 2001)

171. How to add JCheckBox to a JTree

I want to show a Jcheckbox in every node. What should I do?

Sol: see code. Create yourTreeCellRenderer extends checkBox. Or change that in TreeCellEditor.

172. JTree.lineStyle How to change color

"The client property JTree.lineStyle can be set to none to display no lines, to horizontal to display top level lines, and Angled to display hierarchy lines."

My question: Anybody know if you can set/change the color of lineStyle? How?

(I am a visual/graphic designer, grateful for any technical info you can provide)

Sol: You can only change the color globally unless you want to create

a custom UI delegate. To do this, use this code (change the color to whatever suits you):

UIManager.put("Tree.hash", Color.magenta);

If this code is called before you instantiate the JTree component, this will color the hash lines magenta for all JTree objects you create.

173. JTree Expand/Collapse

I have implemented a dynamic JTree which updates itself now and then. It does this by removing all the elements then building them back up again.

The problem I am having is trying to make the program remember the state of the directories, for example, I want to remember which ones have been collapsed and opened by the user so that it looks almost the same the next time they come to use it.

Sol: Don't remove all nodes and add them. Use the methods provided by

the TreeModel to change the structure, add and remove nodes. So

all expanded rows keep expanded and all collapsed are still collapsed.

You must use the method of the model direct, not using the

methods of the MutableTreeNodes as they collapse the tree.

174 The JTree

Does any one knows how to set image specified per node in a JTree

Sol: You have to make your own DefaultTreeCellRenderer. then you can set a personal icon to the node. Example :

class myRenderer extends DefaultTreeCellRenderer {

ImageIcon leafIcon;

public myRenderer()

{

super();

}

public Component

getTreeCellRendererComponent(

JTree tree,

Object value,

boolean sel,

boolean expanded,

boolean leaf,

int row,

boolean hasFocus)

{

super.getTreeCellRendererComponent

(tree,value,sel,expanded,leaf,row,hasFocus);

node noeud = (node) value;

//System.out.println

("node "+noeud.labelName+" ,sel "+sel+" ,expanded "+expanded+" ,l

eaf "+leaf+" ,row "+row+" ,hasFocus "+hasFocus);

switch(<type of node>)

{

case 0 :leafIcon = ....

case 1 :leafIcon = ....

}

setIcon(leafIcon);

return this;

}

}

175 How to select all the entries of a JTree

Seems to be a simple problem but I couldn't find a solution

please tell me if anybody has ever experienced it. How can one

select all the entries of a JTree if the tree has only Parent

nodes(dont tell me to use JList instead I have specific

requirements). Right now I am using the following code to select

all the entries

Object[] anObject = new Object[getAListPane().getRowCount()];

for (int i = 0; i < getAListPane().getRowCount(); i++) {

getAListPane().setSelectionRow(i);

anObject = getAListPane().getSelectedNode().getUserObject();

}

Sol: I remember a postorderEnueration(),

depthFirstEnumeration() etc methods to loop through all the

nodes. So setSelectionMode to MULTIPLE_NODE_SELECTION, then traverse all the nodes and select them.

176 Updating JTree

I am having a hardtime with updating JTree. When i add a new node to the root( it's been added in database and i get notification that something changed in the tree) i am trying to

update the tree. I tried reload, treeNodeChaged()... all those methods with repaint, revalidat.. but no luck. reload worked for the nodes other than root. I do not want to build whole tree again. If i build the whole tree again, then i will have to remember expansion and model will be changed too. Too much work....

Sol: U need to use a DefaultTreeModel and call the method: nodesWereInserted(TreeNode node, int[] childIndices)

177 delete a node from a JTree by clicking Popup Menu action

I am implementing a TreeNodePopup file. when you select a node from a JTree by pressing the left mouse button, then right click, the TreeNodePopup menu shows up, be selecting "delete" action, the selected node will be deleted, but it could not.

178 Custom Edit of JTree Node

When a user selects a node in my JTree and then right clicks, a popup menu appears with the option to rename the node. I need to override the DefaultTreeCellEditor so that it doesn't allow editing of nodes by a triple click, but instead, after the user

selects the rename option on the popup, begins editing the cell and verifies the user input. Does anyone have any ideas on how to do this or maybe some example source?

Sol: "tree.setEditable(false)" will make your JTree not editable. If you use that, however, then you can't edit the node in place. That wasn't a problem for me, though, because I

wanted to bring up a separate panel to edit the entire object in the node and not just its toString() value. However, here's the API documentation for a method I just found in JTree, which might do what you want:

startEditingAtPath(TreePath path): Selects the node identified by the specified path and initiates editing.

179 How to store expanded state of JTree after refershing

I have a JTree in which nodes may be added or deleted quite frequently. Now want that if at any time user refreshes the Tree, the actual expanded state of tree should be restored after refreshing. Please tell me how to achieve it?

180 JTree(Changing color of a specific DefaultMutabletreeNode or changing the icon)

I have a JTree. in that i have 2 types of defaultmutabletreenodes. i want to differentiate these two type of nodes. i am passing a string in the constructor of defaultmutabletreenode.I want to change the color or add an different icon to different type of nodes.

181 JTree selection

I made a JTree but when I select a node that was already selected i can change the name of the node. but I don't want that !!!

Sol: When you click a second time on an already selected node, and if your JTree is in edit mode, you will enter this edit mode. Just turn your JTree in read-only mode by using the setEditable(boolean flag) method on the JTree with the flag to false.



182 How to change icons in a JTree

(Apologies if this seems arrogant) Having read a few posts about

changing the icons in a JTree, it seems that people are

recommending slightly awkward implementations of

TreeCellRenderer, when a simpler approach is possible:

Firstly, create an extension of the DefaultTreeCellRenderer

class as such:

<CODE>

import javax.swing.*;

import javax.swing.tree.*;

public class MyTreeCellRenderer extends DefaultTreeCellRenderer {

public MyTreeCellRenderer()

{

super();

leafIcon = new ImageIcon("myLeafNodeIcon.gif");

closedIcon = new ImageIcon("myClosedParentNodeIcon.gif");

openIcon = new ImageIcon("myOpenParentNodeIcon.gif");

}

}

</CODE>

And then, assuming your JTree is called myJTree, do this:

<CODE>

myJTree.setCellRenderer(new MyTreeCellRenderer());

</CODE>

For the boxes with '+' and '-', simply draw them into your icon.

P.S. have any of you gurus out there managed to draw a

horizontal JTree yet? I'd be interested to know if it's possible

without creating your own classes from scratch.

Sol/Comment : No need to override a render-class to do this. The cellrenderer class actually has a setOpenIcon, setClosedIcon, and setLeafIcon method. U only have to write ur own treecellrenderer if u want something other than that, eg. different open-icons. And those 'akwards' implementations do exactly that.

183 Problem with JTree

I want to add a leaf to a JTree. I think itadded but not shown in the panel.

code:

knoten=new DefaultMutableTreeNode (t.object().toString());

treeModel.insertNodeInto(wurzel,knoten,(wurzel.getIndex(wurzel)+1));

System.out.println("Knoten:"+knoten.toString());

wurzel.add(knoten);

Sol: where are you getting your tree model from? I do someting like this

DefaultTreeModel dtm = (DefaultTreeModel) ruleTree.getModel();

where ruleTree is my JTree. this works for me anyway. If you are using the model you

used to instantiate the JTree itself this could be the problem. It is difficult for me to explain why this is so.. there are many here that can explain it better anyway but think of it like this.

I COULD say

JPanel panel = new JPanel(new FlowLayout());

Component compA = (Component) new JButton("Hello World");

panel.add(compA);

and later...

compA = new JTextField("Hello World");

but this makes things awfully awkward for gui so what seems to happen (to me) is that calling add(Component comp) makes a clone for the container which you can still access through it's methods but you cannot just arbitrarily instatiate new objects because the previously instatiated containers won't point to the same object.

184 Re: change color of a TreeNode on MouseEntered and MouseExited

Author: dassh Jun 4, 2001 11:46 PM

ello,

here is what i am trying to do. i am trying to get a mouseover effect within a JTree (obviously onmouseout as well). I did get this to work with the following code, but when i moved the mouse average speed through the tree nodes, some would not update back to non-selected colors. i have a renderer class and a class which extends DefaultMutableTreeNodes. If i move nice and slow there is no problem...but who moves through a folder tree slowly.

Sol: Just a simple example of a renderer which for rollover effectes (red color of node)

public class MyTreeRenderer extends DefaultTreeCellRenderer {

protected JTree tree;

protected Object lastNode;

public MyTreeRenderer(JTree pTree) {

this.tree = pTree;

tree.addMouseMotionListener(new MouseMotionAdapter() {

public void mouseMoved(MouseEvent me) {

TreePath treePath = tree.getPathForLocation(me.getX(), me.getY());

Object obj;

if (treePath!=null) {

obj = treePath.getLastPathComponent();

} else {

obj = null;

}

if (obj!=lastNode) {

lastNode = obj;

tree.repaint();

}

}

});

}

public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {

Component result = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);

if (value==lastNode) {

((JLabel)result).setForeground(Color.red);

}

return result;

}

}

Maybe you can use anything else than repainting (to repaint only dirty regions...)

185 how replace all item of a JTree

I have a jtree created with new JTree(myvector). I want replace all items with items of another vector. Is it possible ?

Sol: you must use reload method of DefaultTreeModel to refresh your tree.

186 How to set JTree in expanded mode

I got a JTree containing my TreeModel. While launching the screen

jtree display only root node by default. I want to get an expanded tree view when I launch the screen.

187 JTree LookAndFeel

We are using JTree with the DefaultMutableTreeNode constructor.We are not able to see the windows like look and feel.

Sol: Well did you set the Window L&F before instantiating the JTree...by default it is metal L&F...

try{

UIManager.setLookAndFeel

("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");

SwingUtilities.updateComponentTreeUI(workSpaceJtree);

}catch(Throwable e){System.out.println(e);}

Note: Motif/CDE: come.sun.java.swing.plaf.motif.MotifLookAndFeel

Metal: javax.swing.plaf.metal.MetalLookAndFeel

188 Calling JTree experts! How to change a node icon when it is selected

I've got a JTree and what I need is to be able to change the icon on a node when it is selected. I'm using TreeSelectionListener to detect when the node is clicked. I've figured out how to setup different icons for different nodes using a renderer but i'm not sure how to change the icon when a node is selected.

Sol: method 1: in the getTreeCellRendererComponent method of your treecellRenderer,

if(sel)

{

this.setIcon(yourselectedicon);

}

else

this.setIcon(yournonselectedicon);

that should set the icons.

Mehtod 2:

I don't think you'll need to use the TreeSelectionListener. In your TreeCellRenderer, test whether the node is selected and change the icon accordingly.

Try this (for DefaultMutableTreeNode node in JTree tree):

TreeNode[] nodes = node.getPath();TreePath path = new TreePath(nodes);if ( tree.isPathSelected(path) ){ //set selected-node icon...}

There may be a more direct way to do this, and you can cram it all onto one line if you insist.

189 Can't Refresh JTree

I have a JTree displaying what windows are open in my program and whenever I open a folder on the tree it won't refresh anymore?

Sol: By "open a folder on the tree" do you mean you added new nodes to the tree? Make sure you are calling the various fire methods whenever the underlying tree model changes

c.fireTreeNodesInserted ( ... )

190 Updating content in a JScrollPane

I'm storing some data in a Vector and am representing it using a JTree. I currently have a JPanel holding a JScrollPane which contains the JTree. I have a Thread that receives information over the network... which changes the content of the Vector. I want to be able to refresh this JTree to show the changes. I'm not sure how to do this efficiently.

Sol: Be sure your data thread is updating the Tree when no other action is running. Therefore prepare a Runnable to make the update, then post it with SwingUtilities.invokeLater()

191 How can I use JTree to implement File structure...

Please teach me to write such as program about use JTree to implement the File structure . Just like the File Manager in windows 9x.

Sol: see textBook for detail.

192 JTree and Vector

If you create a JTree by passing a Vector, the tree is never updated (display) after adding data to the Vector. Is this because I need to tell the view that the data changed?

Sol:

I think you'll find that the Vector is used to populate the initial tree but there's no connection between the two after that. Once you've created the tree, you can use JTree.getModel() to get the tree's model, cast it to DefaultTreeModel, and work with it that way. (DefaultTreeModel has methods like insertNodeInto etc.

193 JScrollPane and background image

I have a JTree inside of a JScrollPane. Now I want to show a background image behind the JTree (not just set the background color of JTree) Is that possible with JScrollPane ?

Sol: Add a background image to the JTree. You can use this to display your company logo or an evaluation image. Note that this implementation causes the background image to scroll with the tree content.

Using the right CellRenderer is very important for this to work. The DeaultTreeCellRenderer does not work well.

Note: tree.setOpaque(false); and within myTreeCellRenderer, setBackground(null); you must have this, then the paint can work out. See Tree.java

import java.awt.*;

import java.util.*;

import java.awt.event.*;

import javax.swing.*;

import javax.swing.tree.*;

public class Tree

{

public static void main(String[] args)

{

JFrame frame = new JFrame("Table");

frame.addWindowListener( new WindowAdapter() {

public void windowClosing(WindowEvent e)

{

Window win = e.getWindow();

win.setVisible(false);

win.dispose();

System.exit(0);

}

} );

JTree tree = new JTree()

{

ImageIcon image = new ImageIcon( "logo.gif" );

public void paint( Graphics g )

{

// First draw the background image - tiled

Dimension d = getSize();

for( int x = 0; x < d.width; x += image.getIconWidth() )

for( int y = 0; y < d.height; y += image.getIconHeight() )

g.drawImage( image.getImage(), x, y, null, null );

// Now let the regular paint code do it's work

super.paint(g);

}

};

// Set the tree transparent so we can see the background image

tree.setOpaque( false );

tree.setCellRenderer( new MyCellRenderer() );

JScrollPane sp = new JScrollPane( tree );

frame.getContentPane().add( sp );

frame.pack();

frame.show();

}

}



class MyCellRenderer extends JLabel implements TreeCellRenderer

{

public MyCellRenderer()

{

setOpaque(false);

setBackground(null);

}

public Component getTreeCellRendererComponent(JTree tree,

Object value,

boolean sel,

boolean expanded,

boolean leaf,

int row,

boolean hasFocus)

{

setFont(tree.getFont());

String stringValue = tree.convertValueToText(value, sel,

expanded, leaf, row, hasFocus);

setEnabled(tree.isEnabled());

setText(stringValue);

if(sel)

setForeground(Color.blue);

else

setForeground(Color.black);

if (leaf) {

setIcon(UIManager.getIcon("Tree.leafIcon"));

} else if (expanded) {

setIcon(UIManager.getIcon("Tree.openIcon"));

} else {

setIcon(UIManager.getIcon("Tree.closedIcon"));

}

return this;

}

}

Note: From here, I begin the summary work.

194 JLabel problem with ellipss

I've created a rather large JTree, many nodes deep (not sure if this makes a difference). Sometimes, the labels on the tree are ellipsified, i.e. "thisnode" turns to "thisn...", replacing the rest of the string with three dots. Is there a way to turn this off? It's a bit strange since it only happens occasionally.

Sol: Instead of adding the JTree directly to a parent JPanel, create a JScrollPane to view the JTree and then add the JScrollPane. You can then disable the horizontal scrollbar if you really want to.

An ellipsis appears at the end of a row whenever a JTree thinks that the row can't fit in the space provided. This will never happen if the JTree is viewed in a JScrollPane

195 editing in Tree

in my tree I have "House" node out of 10 nodes.

I don't want to edit that particular "House" node.

But as per my code it is editing why?

Sol: //earlier in your code you have created a JTree called, say, "myTree"
//and to it you have added this node:
final DefaultMutableTreeNode houseNode = new DefaultMutableTreeNode("House");
//...
//these variables (finalTree and houseNode) need to be
//declared final so the listener's inner class can "see" them:
final JTree finalTree = myTree;
//then add the listener:
myTree.addTreeSelectionListener(new TreeSelectionListener()
{
public void valueChanged(TreeSelectionEvent e)
{
DefaultMutableTreeNode selectedNode
= (DefaultMutableTreeNode) getLastSelectedPathComponent();
boolean isHouseDescendant = selectedNode.isNodeAncestor(houseNode);
if (isHouseDescendant) {
finalTree.setEditable(false);
}else {
finalTree.setEditable(true);
}

}
});



196 Tree editing

I had used my own renderer for the tree for different icons for different nodes. Now when i edit the tree, it is changing the icons to the default tree icons(leaf and non-leaf) whenever it is in the editable mode. How to edit the tree without changing the icons keeping my own icons

Sol: DefaultTreeCellEditor calls getLeafIcon(), getOpenIcon(),

getClosedIcon() of the DefaultTreeCellRenderer that it takes in

the constructor. The easiest way would be to create a

DefaultTreeCellRenderer, then to call its corresponding set

methods (setLeafIcon(), setOpenIcon(), setClosedIcon()) with

your icons. Then create DefaultTreeCellEditor with this

renderer. And then set it to be the cell editor of you tree with

setCellEditor().

A better alternative is to extend DefaultTreeCellEditor and

overwrite its

protected void determineOffset(JTree tree, Object value,

boolean isSelected, boolean expanded, boolean leaf, int row)

method. In this method it sets its editingIcon member variable

which is then used to draw the icon.



197 Tree Node edit box

I am trying to get the functionality to edit a tree node using popup menus. I can edit the tree node if I click 3 times on the node (a edit box apears over the node). I want to open such a box when I click an option on the popup menu. You can see this edit box in win explorer if you right click and select rename on a folder.



Questions still need to consider

98 visible tree nodes

Is it possible to know if a node (given by its TreePath for instance) is showing in the visible part of a JTree?

I have a big JTree (14000 nodes) and when I repaint it, it is time comsuming.

That's why I would like to repaint the JTree only if the node that must be visually changed (icon) is visible (the user can see it without scrolling or doing any other action on the frame that contains the JTree)

Sol: What about using

if (myTree.isExpanded(myTreePath)) // this path is expanded and is therefore visible....

I've never used it but it seems like it would work...

By the way, you don't have to repaint a tree. You can use a tree model (DefaultTreeModel) and do this:

myTreeModel.reload(nodeToReload);

******************

Part of detailed answers:

1. Want to different types of nodes, such as different color or icons. How to do it?

Sol:

(1). Create your own TreeCellRenderer extends DefaultTreeCellRenderer, overiding the following method:

Public Component getTreeCellRendererComponent(……){

Label comp = (Label) super.getTreeCellRendererComponent(…);

comp.setForeground(Color.red);

comp.setIcon(icon);

return comp;

}

Jtree.setCellRenderer(yourTreeCellRenderer);

(2). UI manager method 1:

ComponentUI treeUI =tree.getUI();

if(treeUI istanceof BasicTreeUI)

{

((BasicTreeUI) treeUI).setExpandedIcon(new ImageIcon ("expand.gif"));

((BasicTreeUI) treeUI).setCollapsedIcon(new ImageIcon ("collapse.gif"));

}

UIManager method 2

If you simply want to chage the node images you can use this:

ImageIcon oicon = new ImageIcon("open.gif");//youropen

ImageIcon cicon = new ImageIcon("closed.gif");//yourclose

ImageIcon bicon = new ImageIcon("bullet.gif");//yourbullet

//UIManager.put("Tree.leafIcon", icon);

UIManager.put("Tree.openIcon", oicon);

UIManager.put("Tree.closedIcon", cicon);

UIManager.put("Tree.leafIcon", bicon);

(3) public class TextIcons extends MetalIconFactory.TreeLeafIcon {

protected String label;

private static Hashtable labels;

protected TextIcons() {

}

public void paintIcon(Component c, Graphics g, int x, int y) {

super.paintIcon( c, g, x, y );

if (label != null) {

FontMetrics fm = g.getFontMetrics();

int offsetX = (getIconWidth() - fm.stringWidth(label)) /2;

int offsetY = (getIconHeight() - fm.getHeight()) /2 - 2;

g.drawString(label, x + offsetX ,

y + offsetY + fm.getHeight());

}

}

public static Icon getIcon(String str) {

if (labels == null) {

labels = new Hashtable();

setDefaultSet();

}

TextIcons icon = new TextIcons();

icon.label = (String)labels.get(str);

return icon;

}

public static void setLabelSet(String ext, String label) {

if (labels == null) {

labels = new Hashtable();

setDefaultSet();

}

labels.put(ext, label);

}

private static void setDefaultSet() {

labels.put("c" ,"C");

labels.put("java" ,"J");

labels.put("html" ,"H");

labels.put("htm" ,"H");

// and so on

}

}

this code is extracted from http://www2.gol.com/users/tame/swing/examples/JTreeExamples2.html

2. Refreshing topic:

(1): Updating the state of component should only occur within the event dispatching thread. So:

Thread runner = new Thread(){

public void run(){

if (somethingHappened){

Runnable runnable = new Runnable(){

public void run(){

model.reload(node);

}

}

SwingUtilities.invokeLater();

}

}

}

runner.start();

(2). DefaultTreeModel Model = tree.getModel();

model.insertNodeInto() and

model.removeNodeFromParent();

This allows you update the tree without reloading it.

RootNode.removeAllChildren();

Model.reload();

(3). Get your tree's model and call nodesWereInserted()/nodesWereRemoved().The best could be to call insertNodeInto() from your DefaultTreeModel. Besides,

model.nodeStructureChanged() and tree.treeDidChange() can get rid of ellipsis.

(4) when using ScrollPane: when you create you add it to the ScrollPane.

cuz i dont know the parent of tree(according to available code), i assume it to be JScrollPane. to change the new tree, (see NO148)

JViewport c = (JViewport)tree.getParent();

tree = getNewTree();

treeModel = (DefaultTreeModel) tree.getModel();

c.setView(tree);

(5). Derive your TreeModel from DefaultTreeModel and override some methods.

Copy some methods from DefaultTreeModel into your own TreeModel. You will need:

1. the methods that will be called from "outside" to perform the

changes on your nodes hierarchy:

insertNodeInto, nodeChanged, removeNodeFromParent

2. the methods to do the internal work:

nodesChanged, nodeStructureChanged, nodesWereInserted,

nodesWereRemoved

3. the corresponding fire... methods:

fireTreeNodesChanged, fireTreeNodesInserted,

fireTreeNodesRemoved, fireTreeStructureChanged

If you have done that, no listeners will be necessary.

Note: it worked after he implements his own fire methods :

fireTreeNodesChanged

fireTreeNodesRemoved



à How do I listen to the event changed by the clicking on the tree node? (selectionListener)

Sol: For the node selection changes, you need to add a listener for that purpose:

tree.addTreeSelectionListener(new TreeSelectionListener()

{

public void valueChanged(TreeSelectionEvent e)

{

DefaultMutableTreeNode node = (DefaultMutableTreeNode)

}// value changed

});// TreeSelectionListener

à How to traverse a JTree which contains jpeg/gif links and display the images in a separate panel? (display in separate panel)

Sol: Method 1:

Add JLabel to JPanel, JPanel to JFrame and then set the JLabel's icon using:

Icon imdefaultTreeCellRenderer.getLeafIcon/getOpenIcon/getClosedIcon();

//Icon im = new ImageIcon("SomeFile.jpg");

jLabel.setIcon(im);

Finally call jFrame.pack() to resize to the image.

Method 2: add to your [separate] panel JEditorPane

JEditorPane srcImagePane = new JEditorPane();

srcImagePane.setContentType ("text/html");

srcImagePane.setEditable (false);

srcImagePane.setText("<img src="yourImage.[gif/jpg]">");

panel.add(srcImagePane);

on "setText(String)" you can add ANY html parameter you need just like you doing that in regular html file such as border=someValue, additional string as an imageName and so on...

à Building a JTree from a database

(1).

I'm attemting to build a Jtree with entries from a database. Each entry knows the id of their parent, so I can easily get an array of all the children at a particular node. My problem is finding the loop that will go through all the entries and add nodes so it matches the database. Does anyone know what kind of loop I need to achieve this?

Sol: (assuming there is a method to get all children for a parent as an array of DefaultMutableTreeNodes):

void addChildren(DefaultMutableTreeNode nodeCurrent)

{

//get the array of tree nodes, or get the array of objects

//which comprise the children and create

//DefaultMutableTreeNodes of them

DefaultMutableTreeNode[] aChildren = getChildren(nodeCurrent);

for(int i = 0; i < aChildren.length; i++)

{

//get the current child

DefaultMutableTreeNode child = aChildren;

//recursively call this method on the current child

addChildren(child);

//add the child to the current node

nodeCurrent.addChild(child);

}

}

Call this initially with the root node. The children of the root node will be retrieved, then the method will be recalled on each of those children. When a leaf node is hit, the recursion stops. Then the children of each node are added from leaf to root. This

should be all you need.

(2). Querying data from a hashTable to build a tree, want the tree with ascending order HashTable treeStuff = <whatever>

List data = new Vector (treeStuff.values());

Collections.sort(data);

JTree tree = new JTree(data);

JTree(Hashtable value)
Returns a JTree created from a Hashtable which does not display with root.

(3). Use a TreeWillExpandListener rather than a TreeExpansionListener. That gives your program time to fill in the nodes when it finds the user has asked to expand their parent.

So try TreeWillExpandListener instead.

à Customizing selection in a JTree (leaf selection)

I need to customize the way a JTree selection behaves in the following way:

1. A user should be able to select multiple leaves, and leaves only.

2. Selected leaves can only be part of a single "folder" (non-leaf node)

The problem is that the selection is handled by the JTree and I can only get a notification the the selection HAS CHANGED. I can't prevent the change.... Adding a mouse (or a keyboard) listener to the JTree does not help, since it has already a mouse listener that triggers the selection change.

Sol: The following code should allow leaf selection only:

public class LeafOnlyTreeSelectionModel extends

DefaultTreeSelectionModel {

public void addSelectionPath(TreePath path)

{

DefaultMutableTreeNode lastComp =

(DefaultMutableTreeNode)path.getLastPathComponent();

if (lastComp.isLeaf()) {

super.addSelectionPath(path);

}

}

public void addSelectionPaths(TreePath[] paths)

{

for (int i = 0 ; i < paths.length ; i++) {

DefaultMutableTreeNode lastComp =

(DefaultMutableTreeNode)paths.getLastPathComponent();

if (!lastComp.isLeaf()) {

return;

}

}

super.addSelectionPaths(paths);

}

public void setSelectionPath(TreePath path)

{

DefaultMutableTreeNode lastComp =

(DefaultMutableTreeNode)path.getLastPathComponent();

if (lastComp.isLeaf()) {

super.setSelectionPath(path);

}

}

public void setSelectionPaths(TreePath[] paths)

{

for (int i = 0 ; i < paths.length ; i++) {

DefaultMutableTreeNode lastComp =

(DefaultMutableTreeNode)paths.getLastPathComponent();

if (!lastComp.isLeaf()) {

return;

}

}

super.setSelectionPaths(paths);

}

}

*********************

code : AlternativeView.java

import javax.swing.*;

import javax.swing.tree.*;

import java.util.*;

public class AlternativeView {

public static void recursive(StringBuffer s, Object node) {

if (node == null) return;

s.append(node);

if (!(node instanceof TreeNode)) return;

TreeNode n = (TreeNode) node;

if (n.isLeaf()) return;

s.append("(");

boolean first = true;

for (Enumeration e = n.children(); e.hasMoreElements(); ) {

if (!first) s.append(",");

recursive(s, e.nextElement());

first = false;

}

s.append(")");

}

public static String parseTree(JTree tree) {

if (tree == null) return null;

StringBuffer s = new StringBuffer();

recursive(s, tree.getModel().getRoot());

return s.toString();

}

public static void main(String[] args) {

JTree tree = new JTree();

System.out.println(parseTree(tree));

}

}

************************

Use CheckBox for node:

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import javax.swing.event.*;

import javax.swing.tree.*;

import java.util.*;

/*<applet code=JTree_CheckBox width=300 height=300></applet>*/

public class JTree_CheckBox extends JApplet

{

JTree tree=new JTree();

public void init()

{

JScrollPane pane=new JScrollPane(tree);

getContentPane().add(pane);

JCheckBox checkbox=new JCheckBox("bjk");

JTextField field =new JTextField();

tree.setCellEditor(new SetUpCheckBox(tree,checkbox));

tree.setEditable(true);

}

}

class SetUpCheckBox extends DefaultCellEditor

{

JPanel panel=new JPanel();

private JTree tree;

public SetUpCheckBox(JTree tree,JCheckBox checkbox)

{

super(checkbox);

this.tree=tree;

Component struct=Box.createHorizontalStrut(5);

panel.add(struct);

panel.add(checkbox);



}

}

**********************

Mouse Enter and Exit a node (color change)

public class MyTreeRenderer extends DefaultTreeCellRenderer {

protected JTree tree;

protected Object lastNode;

public MyTreeRenderer(JTree pTree) {

this.tree = pTree;

tree.addMouseMotionListener(new MouseMotionAdapter() {

public void mouseMoved(MouseEvent me) {

TreePath treePath = tree.getPathForLocation(me.getX(), me.getY());

Object obj;

if (treePath!=null) {

obj = treePath.getLastPathComponent();

} else {

obj = null;

}

if (obj!=lastNode) {

lastNode = obj;

tree.repaint();

}

}

});

}

public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {

Component result = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);

if (value==lastNode) {

((JLabel)result).setForeground(Color.red);

}

return result;

}

}

CheckBox on leaf:

Q: I was able to put Checkboxes on the leaves, but I'm having a hard time controlling when the boxes get checked and unchecked.

A: JTree uses the TreeCellRenderer as a way to stamp regions on the

screen, it merely uses the paint method of the Component given

by getTreeCellRendererComponent to paint the appropriate region.

The checkbox you're seeing on the screen in the JTree is not an

actual component, i.e. it doesn't actually receive mouse events.

You will have to catch the MouseEvents coming to the JTree by

adding a MouseListener to the JTree. The JTree does this for

performance reasons as having a 100's of components takes up

quite a bit of processing time.

taken from the documentation for JTree,

final JTree tree = ...;

MouseListener ml = new MouseAdapter() {

public void mousePressed(MouseEvent e) {

int selRow = tree.getRowForLocation(e.getX(), e.getY());

TreePath selPath = tree.getPathForLocation(e.getX(),

e.getY());

if(selRow != -1) {

if(e.getClickCount() == 1) {

mySingleClick(selRow, selPath);

}

else if(e.getClickCount() == 2) {

myDoubleClick(selRow, selPath);

}

}

}

};

tree.addMouseListener(ml);

You know which node the user clicked on, so you can then change

how the JCheckbox is configured when handed to the JTree by

getCellRendererComponent.

public Component getCellRendererComponent(...){

// if you use the typical TreeNode usage

TreeNode node = (TreeNode)value;

Object myObject = node.getUserObject();

if(myObject.isChecked()){

checkBox.setSelected(true);

}else{

checkBox.setSelected(false);

}

return checkBox;

}

*****************

open nodes detection: Sample code:

Vector expandedNodes = new Vector();

getExpandedNodes(MyDefaultMutableTreeNode root, expandedNodes);

// Here is the method,

void getExpandedNodes(MyDefaultMutableTreeNode pNode, Vector

eNodes)

{

Enumeration enum = pNode.children();

while(enum.hasMoreElements()) {

MyDefaultMutableTreeNode cNode =

(MyDefaultMutableTreeNode)enum.nextElement();

if(cNode.isExpanded()) {

// add it to the list

eNodes.addElement(cNode);

getExpandedNodes(cNode, eNodes);

} else {

// if you want to consider the nodes under this

// non-expanded node, you need to uncomment the line

// below

// getExpandedNodes(cNode, eNodes);

}

}

return eNodes;

}

*******************

Tree Background image:

You can use this to display your company logo or an evaluation image. Note that this implementation causes the background image to scroll with the tree content.

Using the right CellRenderer is very important for this to work. The DeaultTreeCellRenderer does not work well.

Note: tree.setOpaque(false); and within myTreeCellRenderer, setBackground(null); you must have this, then the paint can work out. See Tree.java

import java.awt.*;

import java.util.*;

import java.awt.event.*;

import javax.swing.*;

import javax.swing.tree.*;

public class Tree

{

public static void main(String[] args)

{

JFrame frame = new JFrame("Table");

frame.addWindowListener( new WindowAdapter() {

public void windowClosing(WindowEvent e)

{

Window win = e.getWindow();

win.setVisible(false);

win.dispose();

System.exit(0);

}

} );

JTree tree = new JTree()

{

ImageIcon image = new ImageIcon( "logo.gif" );

public void paint( Graphics g )

{

// First draw the background image - tiled

Dimension d = getSize();

for( int x = 0; x < d.width; x += image.getIconWidth() )

for( int y = 0; y < d.height; y += image.getIconHeight() )

g.drawImage( image.getImage(), x, y, null, null );

// Now let the regular paint code do it's work

super.paint(g);

}

};

// Set the tree transparent so we can see the background image

tree.setOpaque( false );

tree.setCellRenderer( new MyCellRenderer() );

JScrollPane sp = new JScrollPane( tree );

frame.getContentPane().add( sp );

frame.pack();

frame.show();

}

}



class MyCellRenderer extends JLabel implements TreeCellRenderer

{

public MyCellRenderer()

{

setOpaque(false);

setBackground(null);

}

public Component getTreeCellRendererComponent(JTree tree,

Object value,

boolean sel,

boolean expanded,

boolean leaf,

int row,

boolean hasFocus)

{

setFont(tree.getFont());

String stringValue = tree.convertValueToText(value, sel,

expanded, leaf, row, hasFocus);

setEnabled(tree.isEnabled());

setText(stringValue);

if(sel)

setForeground(Color.blue);

else

setForeground(Color.black);

if (leaf) {

setIcon(UIManager.getIcon("Tree.leafIcon"));

} else if (expanded) {

setIcon(UIManager.getIcon("Tree.openIcon"));

} else {

setIcon(UIManager.getIcon("Tree.closedIcon"));

}

return this;

}

}

*****************

Tree Transparent topic

You must set the non/selectionColor to an opaque color (alpha =1)

myTree.setOpaque(false);

DefaultTreeCellRenderer cr = new DefaultTreeCellRenderer();

Color op = new Color(0,0,0,1);

cr.setBackgroundNonSelectionColor(op);

myTree.setCellRenderer(cr);

Method 2: In YourCellRenderer class:

m_textSelectionColor = UIManager.getColor( "Tree.selectionForground" );

m_textNonSelectionColor = UIManager.getColor( "Tree.textForeground" );

m_bkSelectionColor = UIManager.getColor( "Tree.SelectionBackground" );

m_bkNoSelectionColor = UIManager.getColor( "Tree.textBackground" );

then:

setForeground(select? m_textSelectionColor: m_textNonSelectionColor);

setBackground(select? m_bkSelectionColor: m_bkNonSelectionColor);