An Expandable JTree Problem
Hi, I'm relatively new to creating JTree components, now I have looked at many examples, and this one is nearest (i can see) to how I want my Jtree to look, however it doesn't behave in a way which I would like!
Firstly, I can set the root node to have as many folders as i want, however they only mirror whats in the first root node, I dont want this - I want to be able to create about 5/6 different roots that will yield different results - I also want after each time you click on a folder, which will ask a question about a patient i.e. "Has the patient a head injury" - click on this then it should come up with "3" more different choices, so altogther want it about 5 deep.
However, this is what I've got so far - but like I say, its not yielding the results I want, does anyone know how to modify this or can anyone point me in the right direction by starting me off a bit, that would be great!
import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.event.*;
public class SelectableTree extends JFrame
implements TreeSelectionListener {
public static void main(String[] args) {
new SelectableTree();
private JTree tree;
private JTextField currentSelectionField;
public SelectableTree() {
super("Clinical Information Help System");
WindowUtilities.setNativeLookAndFeel();
addWindowListener(new ExitListener());
Container content = getContentPane();
DefaultMutableTreeNode root =
new DefaultMutableTreeNode("Begin Clinical Questions");
DefaultMutableTreeNode child = null;
DefaultMutableTreeNode parent = null;
DefaultMutableTreeNode grandChild = null;
DefaultMutableTreeNode grandParent = null;
DefaultMutableTreeNode child2 = null;
DefaultMutableTreeNode parents = null;
for(int grandParentIndex=1; grandParentIndex < 2; grandParentIndex++) {
grandParent = new DefaultMutableTreeNode("[Does Patient Have Back Pains?] " + grandParentIndex);
root.add(grandParent);
for(int parentIndex =1; parentIndex < 3; parentIndex++) {
parent = new DefaultMutableTreeNode("[Does the patient also have leg pain?] " + parentIndex +
"." + parentIndex);
grandParent.add(parent);
for(int childIndex =1; childIndex < 3; childIndex++) {
child = new DefaultMutableTreeNode("[are the pains in the lower back?] " + childIndex +
"." + childIndex);
parent.add(child);
child2 = new DefaultMutableTreeNode("patient over 60?" + childIndex +
"." + childIndex);
child.add(child2);
for(int grandChildIndex =1; grandChildIndex < 3; grandChildIndex++) {
grandChild = new DefaultMutableTreeNode("[Does patient have bladder and/or bowel incontinence?] " + grandChildIndex +
"." + grandChildIndex);
child.add(grandChild);
for(int childIndex = 1; childIndex < 3; childIndex++) {
child = new DefaultMutableTreeNode("[Has Patient suffered either: appitite/wieght loss/fever?]" + childIndex +
"." + childIndex);
child = new DefaultMutableTreeNode("[Has pain been 4-6wks leg pain? OR 3-6mths low-back pain?]" + childIndex +
"." + childIndex);
grandChild.add(child);
tree = new JTree(root);
//tree = new JTree(root2);
tree.addTreeSelectionListener(this);
content.add(new JScrollPane(tree), BorderLayout.CENTER);
currentSelectionField = new JTextField("Current Selection: NONE");
content.add(currentSelectionField, BorderLayout.SOUTH);
setSize(400, 400);
setVisible(true);
public void valueChanged(TreeSelectionEvent event) {
currentSelectionField.setText
("Current Selection: " +
tree.getLastSelectedPathComponent().toString());
}
I'm not really sure what your problem is, for I don't see what you mean by "mirror". If it is you have but one root node, but wanted to have many instead, then you'd simply need to call setRootVisible(false); on the tree.
As a sidenote, I don't think it's a really good UI for what you're doing, but after all, I haven't got the whole picture.
Now, what is it you mean by: its not yielding the results I want ?
Similar Messages
-
Hi,
I have got question how to expand JTree. I am using netbeans IDE.
I would like to save information about last visited position in tree and when I open this window again to expand it to last visited node(leaf).
I have done someting like that:
String hostName = getHostName();
DefaultMutableTreeNode root = new DefaultMutableTreeNode(hostName)
DefaultTreeModel treeModel = new DefaultTreeModel(root);
JTree jTree1 = new JTree();
jTree1.setModel(treeModel);
//I have create method to create jTree:
public void setTree(TreePath path)
DefaultMutableTreeNode newNode;
//Here I call method to get all root folders. For root it will be all disks.
File[] folderList = getFolders(...)
for(File f: folderList)
newNode = new DefaultMutableTreeNode(f);
root.add(newNode);
Ok. That's how it create jTree. This part of code works correct. I invoke this window with other (main) window. I have got treeNode e.g.
[ TRAVEL, C:\, C:\Program Files ]
I strange because I checked that on second level node has leaf but it doesn't handle and folder icon. I have tried jTree1.repaint but it doesn't work.
How can I expand tree to this node. I have been trying:
--scrollPathToVisible method
When I select a node by mouse clicking then tree refreshes and show handle with folder icon and all leafs. I have selected the same node using setSelectionPath(treePath) but it is not working and trying to expand it but it is not working.
Give me a sign if you need more information.
Peter D.It only took me 20 seconds to do a search and find this, but since you've waited over five hours, here's one result I found
http://forum.java.sun.com/thread.jsp?forum=31&thread=257313 -
I have been working all morning to add a horizontal spry menu
bar to the menu_bar section of the Mother Earth Template (
http://www.webshapes.org/template/details/id/200702247034127204)
from Webshapes (
http://www.webshapes.org/)
Anyway, I had to do some crazy positioning to get the
submenus to lign up with the menus and now the submenus will not
display in IE because of an 'expanding box problem' All of the
problems are associated with either my "ul.MenuBarHorizontal ul" or
my "ul.MenuBarHorizontal ul ul"
Can anyone help me with this? I am a beginner with
Dreamweaver and have been having a lot of troubles with it.
Thanks.Hello Tom, Is it a template related error message?
I would suggest you to use percentages when setting the width
and height values. -
Spry Vertical Submenu - Expanding Box Problem, white background
Hello everyone. I've recently incorporated a Spry Vertical Menu on my site for the first time and I'm experiencing problems with the submenu in IE7. (Things look fine in FF, Safari, and Opera.) A white box appears behind the text area (the "bios" and "contact us" links). And....In IE6 the entire menu bar becomes a horizontal mess.
I've come to learn that this is called an Expanding Box Problem but I don't know how to fix it. Perhaps this is seperate issue from the white panel issue altogether. I dunno. Can anyone be of assistance? I've been trying to solve this problem for days.
http://www.exposedproductionsnyc.com
Below is the CSS:
/* The outermost container of the Menu Bar, a fixed width box with no margin or padding */
ul.MenuBarVertical
list-style-type: none;
font-size: 100%;
cursor: default;
width: 8em;
padding-top: 0px;
padding-right: 0;
padding-bottom: 0;
padding-left: 31.5px;
background-color: #000;
margin-top: 0;
margin-right: 0;
margin-bottom: 0;
margin-left: 0;
/* Set the active Menu Bar with this class, currently setting z-index to accomodate IE rendering bug: http://therealcrisp.xs4all.nl/meuk/IE-zindexbug.html */
ul.MenuBarActive
z-index: 1000;
/* Menu item containers, position children relative to this container and are same fixed width as parent */
ul.MenuBarVertical li
margin: 0;
padding: 0;
list-style-type: none;
font-size: 100%;
position: relative;
text-align: left;
cursor: pointer;
width: 160px;
background-color: #000;
/* Submenus should appear slightly overlapping to the right (95%) and up (-5%) with a higher z-index, but they are initially off the left side of the screen (-1000em) */
ul.MenuBarVertical ul
margin: -5% 0 0 95%;
padding: 0;
list-style-type: none;
font-size: 100%;
position: absolute;
z-index: 1020;
cursor: default;
width: 8.2em;
left: -1000em;
top: 0;
/* Submenu that is showing with class designation MenuBarSubmenuVisible, we set left to 0 so it comes onto the screen */
ul.MenuBarVertical ul.MenuBarSubmenuVisible
left: 0;
/* Menu item containers are same fixed width as parent */
ul.MenuBarVertical ul li
width: 100px;
padding-left: 29px;
padding-top: 3px;
margin-top: 1px;
DESIGN INFORMATION: describes color scheme, borders, fonts
/* Outermost menu container has borders on all sides */
ul.MenuBarVertical
/* Submenu containers have borders on all sides */
/*ul.MenuBarVertical ul
border: 1px none #CCC;
/* Menu items are a light gray block with padding and no text decoration */
ul.MenuBarVertical a
display: block;
cursor: pointer;
background-color: #000;
padding: 0.5em 0em;
color: #FFF;
text-decoration: none;
/* Menu items that have mouse over or focus have a blue background and white text */
ul.MenuBarVertical a:hover, ul.MenuBarVertical a:focus
background-color: #000;
color: #6CC3D7;
/* Menu items that are open with submenus are set to MenuBarItemHover with a blue background and white text */
ul.MenuBarVertical a.MenuBarItemHover, ul.MenuBarVertical a.MenuBarItemSubmenuHover, ul.MenuBarVertical a.MenuBarSubmenuVisible
background-color: #000;
color: #6CC3D7;
SUBMENU INDICATION: styles if there is a submenu under a given menu item
/* Menu items that have a submenu have the class designation MenuBarItemSubmenu and are set to use a background image positioned on the far left (95%) and centered vertically (50%) */
ul.MenuBarVertical a.MenuBarItemSubmenu
background-image: url(SpryMenuBarRight.gif);
background-repeat: no-repeat;
background-position: 95% 50%;
background-color: transparent;
/* Menu items that are open with submenus have the class designation MenuBarItemSubmenuHover and are set to use a "hover" background image positioned on the far left (95%) and centered vertically (50%) */
ul.MenuBarVertical a.MenuBarItemSubmenuHover
background-image: url(SpryMenuBarRightHover.gif);
background-repeat: no-repeat;
background-position: 95% 50%;
background-color: transparent;
BROWSER HACKS: the hacks below should not be changed unless you are an expert
/* HACK FOR IE: to make sure the sub menus show above form controls, we underlay each submenu with an iframe */
ul.MenuBarVertical iframe
position: absolute;
z-index: 1010;
filter:alpha(opacity:0.1);
/* HACK FOR IE: to stabilize appearance of menu items; the slash in float is to keep IE 5.0 from parsing */
@media screen, projection
ul.MenuBarVertical li.MenuBarItemIE
display: inline;
f\loat: left;Long answer = z-index
http://www.smashingmagazine.com/2009/09/15/the-z-index-css-property-a-comprehensive-look/
Nancy O. -
Expanding box problem in some browsers
My bottom three dividers are having an expanding box problem in some browers. Any idea how to fix? This is my first website and I am clueless.....
www.privateinsurancebrokers.com
Source Code:
V <div id="container">
<div id="main_image"><img src="Images/ThreeArch.jpg" width="960" height="400" alt="Kenneth G. Harris Insurance Agency" /></div>
<div id="left_colum">
<strong><a href="employeebenefits.html"><img src="Images/Website_EmployeeBenefits.jpg" width="310" height="127" alt="Employee Benefits Orange County" /></a>Employee Benefits
</strong><br />
Since 1972, Kenneth G. Harris Insurance Agency has advocated for our clients in the process of securing the highest value employee benefit program. <a href="employeebenefits.html" target="_new">Learn More»</a> </div>
<div id="center_column"><strong><a href="HealthInsurance.html"><img src="Images/Family and Individual Insurance.jpg" alt="Family and Individual Insurance Services" width="310" height="127" align="top" /></a>Individual & Family Insurance Services
</strong>Kenneth G. Harris Insurance Agency will work with our insurance and financial partners to assist you with all aspects of your personal insurance needs. <a href="individualinsurance.html" target="_new">Learn More»</a></div>
<div id="right_column"><a href="news.html"><img src="Images/blog.jpg" width="310" height="127" alt="Health and Life Insurance News Orange County" /></a>
<strong>Information</strong> <br />
Keep up-to-date with the latest employee benefits and private insurance news. Let us serve as your resource for health care reform news and<a href="article2.html" title="Kenneth G. Harris Insurance Agency Group Health and Individual Insurance" target="_new"> more»</a></div>
</div>Your CSS Layout has a provision for clearing floats but I don't see it in your HTML markup.
Insert a float clearing <br> <p> or <hr> right above your footer division like so:
<hr class="clearfloat" />
<div class="footer">
Nancy O.
Alt-Web Design & Publishing
Web | Graphics | Print | Media Specialists
http://alt-web.com/
http://twitter.com/altweb -
JTree with XML content expand/collapse problem
Hello all,
I'm having this very weird problem with a JTree I use to display the contents of an XML file. I use the DOM parser (and not JDOM since I want the application to run as an applet as well, and don't want to have any external libraries for the user to download) and have a custom TreeModel and TreeNode implementations to wrap the DOM nodes so that they are displayed by the JTree.
I have also added a popup menu in the tree, for the user to be able to expand/collapse all nodes under the selected one (i.e. a recursive method).
When expandAll is run, everything works fine and the children of the selected node are expanded (and their children and so on).
However, after the expansion when I run the collapseAll function, even though the selected node collapses, when I re-expand it (manually not by expandAll) all of it's children are still fully open! Even if I collapse sub-elements of the node manually and then collapse this node and re-expand it, it "forgets" the state of it's children and shows them fully expanded.
In other words once I use expandAll no matter what I do, the children of this node will be expanded (once I close it and re-open it).
Also after running expandAll the behaviour(!) of the expanded nodes change: i have tree.setToggleClickCount(1); but on the expanded nodes I need to double-click to collapse them.
I believe the problem is related to my implementations of TreeModel and TreeNode but after many-many hours of trying to figure out what's happening I'm desperate... Please help!
Here's my code:
public class XMLTreeNode implements TreeNode
//This class wraps a DOM node
org.w3c.dom.Node domNode;
protected boolean allowChildren;
protected Vector children;
//compressed view (#text).
private static boolean compress = true;
// An array of names for DOM node-types
// (Array indexes = nodeType() values.)
static final String[] typeName = {
"none",
"Element",
"Attr",
"Text",
"CDATA",
"EntityRef",
"Entity",
"ProcInstr",
"Comment",
"Document",
"DocType",
"DocFragment",
"Notation",
static final int ELEMENT_TYPE = 1;
static final int ATTR_TYPE = 2;
static final int TEXT_TYPE = 3;
static final int CDATA_TYPE = 4;
static final int ENTITYREF_TYPE = 5;
static final int ENTITY_TYPE = 6;
static final int PROCINSTR_TYPE = 7;
static final int COMMENT_TYPE = 8;
static final int DOCUMENT_TYPE = 9;
static final int DOCTYPE_TYPE = 10;
static final int DOCFRAG_TYPE = 11;
static final int NOTATION_TYPE = 12;
// The list of elements to display in the tree
static String[] treeElementNames = {
"node",
// Construct an Adapter node from a DOM node
public XMLTreeNode(org.w3c.dom.Node node) {
domNode = node;
public String toString(){
if (domNode.hasAttributes()){
return domNode.getAttributes().getNamedItem("label").getNodeValue();
}else return domNode.getNodeName();
public boolean isLeaf(){
return (this.getChildCount()==0);
boolean treeElement(String elementName) {
for (int i=0; i<treeElementNames.length; i++) {
if ( elementName.equals(treeElementNames)) return true;
return false;
public int getChildCount() {
if (!compress) {
return domNode.getChildNodes().getLength();
int count = 0;
for (int i=0; i<domNode.getChildNodes().getLength(); i++) {
org.w3c.dom.Node node = domNode.getChildNodes().item(i);
if (node.getNodeType() == ELEMENT_TYPE
&& treeElement( node.getNodeName() ))
// Note:
// Have to check for proper type.
// The DOCTYPE element also has the right name
++count;
return count;
public boolean getAllowsChildren() {
// TODO Auto-generated method stub
return true;
public Enumeration children() {
// TODO Auto-generated method stub
return null;
public TreeNode getParent() {
// TODO Auto-generated method stub
return null;
public TreeNode getChildAt(int searchIndex) {
org.w3c.dom.Node node =
domNode.getChildNodes().item(searchIndex);
if (compress) {
// Return Nth displayable node
int elementNodeIndex = 0;
for (int i=0; i<domNode.getChildNodes().getLength(); i++) {
node = domNode.getChildNodes().item(i);
if (node.getNodeType() == ELEMENT_TYPE
&& treeElement( node.getNodeName() )
&& elementNodeIndex++ == searchIndex) {
break;
return new XMLTreeNode(node);
public int getIndex(TreeNode tnode) {
if (tnode== null) {
throw new IllegalArgumentException("argument is null");
XMLTreeNode child=(XMLTreeNode)tnode;
int count = getChildCount();
for (int i=0; i<count; i++) {
XMLTreeNode n = (XMLTreeNode)this.getChildAt(i);
if (child.domNode == n.domNode) return i;
return -1; // Should never get here.
public class XMLTreeModel2 extends DefaultTreeModel
private Vector listenerList = new Vector();
* This adapter converts the current Document (a DOM) into
* a JTree model.
private Document document;
public XMLTreeModel2 (Document doc){
super(new XMLTreeNode(doc));
this.document=doc;
public Object getRoot() {
//System.err.println("Returning root: " +document);
return new XMLTreeNode(document);
public boolean isLeaf(Object aNode) {
return ((XMLTreeNode)aNode).isLeaf();
public int getChildCount(Object parent) {
XMLTreeNode node = (XMLTreeNode) parent;
return node.getChildCount();
public Object getChild(Object parent, int index) {
XMLTreeNode node = (XMLTreeNode) parent;
return node.getChildAt(index);
public int getIndexOfChild(Object parent, Object child) {
if (parent==null || child==null )
return -1;
XMLTreeNode node = (XMLTreeNode) parent;
return node.getIndex((XMLTreeNode) child);
public void valueForPathChanged(TreePath path, Object newValue) {
// Null. no changes
public void addTreeModelListener(TreeModelListener listener) {
if ( listener != null
&& ! listenerList.contains( listener ) ) {
listenerList.addElement( listener );
public void removeTreeModelListener(TreeModelListener listener) {
if ( listener != null ) {
listenerList.removeElement( listener );
public void fireTreeNodesChanged( TreeModelEvent e ) {
Enumeration listeners = listenerList.elements();
while ( listeners.hasMoreElements() ) {
TreeModelListener listener =
(TreeModelListener) listeners.nextElement();
listener.treeNodesChanged( e );
public void fireTreeNodesInserted( TreeModelEvent e ) {
Enumeration listeners = listenerList.elements();
while ( listeners.hasMoreElements() ) {
TreeModelListener listener =
(TreeModelListener) listeners.nextElement();
listener.treeNodesInserted( e );
public void fireTreeNodesRemoved( TreeModelEvent e ) {
Enumeration listeners = listenerList.elements();
while ( listeners.hasMoreElements() ) {
TreeModelListener listener =
(TreeModelListener) listeners.nextElement();
listener.treeNodesRemoved( e );
public void fireTreeStructureChanged( TreeModelEvent e ) {
Enumeration listeners = listenerList.elements();
while ( listeners.hasMoreElements() ) {
TreeModelListener listener =
(TreeModelListener) listeners.nextElement();
listener.treeStructureChanged( e );
The collapseAll, expandAll code (even though I m pretty sure that's not the problem since they work fine on a normal JTree):
private void collapseAll(TreePath tp){
if (tp==null) return;
Object node=tp.getLastPathComponent();
TreeModel model=tree.getModel();
if (!model.isLeaf(node)){
tree.collapsePath(tp);
for (int i=0;i<model.getChildCount(node);i++){
//for (int i = node.childCount()-4;i>=0;i--){
collapseAll(tp.pathByAddingChild(model.getChild(node,i)));
tree.collapsePath(tp);
private void expandAll(TreePath tp){
if (tp==null) return;
Object node=tp.getLastPathComponent();
TreeModel model=tree.getModel();
if (!model.isLeaf(node)){
tree.expandPath(tp);
for (int i=0;i<model.getChildCount(node);i++){
//for (int i = node.childCount()-4;i>=0;i--){
expandAll(tp.pathByAddingChild(model.getChild(node,i)));Hi,
Iam not facing this problem. To CollapseAll, I do a tree.getModel().reload() which causes all nodes to get collapsed and remain so even if I reopen them manually.
Hope this helps.
cheers,
vidyut -
JTree - problems with names of elements
I have a Jtree thats populated with expandable elements. These elements are loaded on startup, but some of the elements don't get their full names, just i.e "dem..." instead of "demo3". WHen I expand the node, the full name appears, and remains.
Anyone know what this could be?
The problem is really often associated with nodes with names containing "m" ..By default the tree node renderer is JLabel.
It look like you are not using pack() or validate().
It depend also the layout manager you are using.
In one word, it seems the JLabel has dimension too short.
Can only show 3 to 4 char. that is why "demo3" show as "dem..."
Try have some node name like "WWWWW", if you see "WW..." or "WWW..."
Then that is the problem. ( Not as you thought: only "m" has problem ) -
Any component as leaf for JTree problems
hi,
I'm trying to get arbitary components as leaves in a JTree and it looks like its very nearly there, but there are two (related?) problems.
1) If you click around on the top 3 tree components then it gets stuck in a loop of rendering and causes a stack exception to be thrown.
2) For the embedded JTree component, expanding its nodes doesn't update the parent tree
both may be because current the row height is set at the wrong time (in the TreeCellRenderer)
any help would be really appreciated!
thanks,
asjf
import javax.swing.*;
import javax.swing.tree.*;
import java.awt.*;
import java.util.*;
public class ComponentTree
public static void main(String args[])
try{(new UIManager()).setLookAndFeel((new UIManager()).getSystemLookAndFeelClassName());}
catch(Exception e){}
DefaultMutableTreeNode c0 = new DefaultMutableTreeNode(new JButton("root"));
DefaultMutableTreeNode c1 = new DefaultMutableTreeNode(new JButton("c1"));
DefaultMutableTreeNode c2 = new DefaultMutableTreeNode(new JList(new Object [] {"A","B","C"}));
DefaultMutableTreeNode c3 = new DefaultMutableTreeNode(new JTable(new Object [][] {{"Active","true"},{"User","root"}}, new Object [] {"Name","Value"}));
DefaultMutableTreeNode c4 = new DefaultMutableTreeNode(new JTree());
DefaultMutableTreeNode c5 = new DefaultMutableTreeNode(new JList(new Object [] {"D","E","F"}));
DefaultMutableTreeNode c6 = new DefaultMutableTreeNode(new JCheckBox("Active",true));
DefaultTreeModel dtm = new DefaultTreeModel(c0);
dtm.insertNodeInto(c6,c0,0);
dtm.insertNodeInto(c1,c0,0);
dtm.insertNodeInto(c2,c0,0);
dtm.insertNodeInto(c5,c2,0);
dtm.insertNodeInto(c3,c1,0);
dtm.insertNodeInto(c4,c3,0);
JTree tree = new JTree(dtm);
tree.setEditable(true);
tree.setCellRenderer(new DefaultTreeCellRenderer()
public Component getTreeCellRendererComponent( JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row, boolean hasFocus)
System.out.println("Render row "+row);
Component c = (Component) ((DefaultMutableTreeNode) value).getUserObject();
if(c instanceof JCheckBox)
c.setBackground(UIManager.getColor("Tree.textBackground"));
tree.setRowHeight(c.getHeight());
return c;
tree.setCellEditor(new DefaultTreeCellEditor(tree,(DefaultTreeCellRenderer)tree.getCellRenderer())
public boolean isCellEditable(EventObject evt){return true;}
public Component getTreeCellEditorComponent( JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row)
return (Component) ((DefaultMutableTreeNode) value).getUserObject();
JFrame frame = new JFrame("ComponentTree");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(tree);
frame.pack();
frame.show();
}thanks!
this seems an awful lot of code to get this working - it should be possible to have a single CellEditor/Renderer??
also running the code - its very hard to select checkbox items, and the JLists seem to disable themselves when the main tree updates?
its also not general to any Component (?) (although we probably only want JComponent) so we can't add a JTree as a leaf?
I'm guessing there is a simpler way to get this working? -
JTree: Problems updating the nodes size
Hi,
I'm trying to update the content of a JTree and I wonder how it
really works, since the paint() method doesn't seem to call the
renderer.
My situation: Imagine a JPanel splited in two by a JSplitPane. In
the left is the tree. Each node in the tree shows two panels, one
aligned to the left, and another to the right. I need that the panel
containing the two use all the available space in the left part of the
Split panel.
My solution: I pass the left JPanel to the tree renderer, so that
it can get the width from it (inside the
getTreeCellRendererComponent()) to build the return JPanel with the
correct size. My logic is that since each time you move the JSplitPane
the JTree paint() method is invoked the renderer can return the
correct JPanel with the correct size that will be painted then in the
screen.
My problem: Doens't work. When I render the tree, the renderer is
invoked, but it doesn't change its size (I can change the color based on the width, but not the node size). Only when I collapse & expand a node, it correctly takes into account the .setPreferredSize() and returns the JPanel with the correct size.
The only way I found to update the tree involves to catch the
JSplitPane event and call updateUI() in the tree, something that, I
think, it's certainly not the correct way to do it.
Any explanation of why this doesn't work would be really great. Any
pointer to a web resource explaining in deep how Swing components work (specially the JTree) would be a godsend.
Thanks,
- JuanchoMy situation: Imagine a JPanel splited in two by a JSplitPane. Got it.
In the left is the tree. In the left side of the JSplitPane is a JTree.
Each node in the tree shows two panels,Maybe... on the right side of the JSplitPane are two Panels in which the data depends on which node is selected in the JTree???
Maybe... you have a custom TreeCellRenderer which displays a pair of panels in place of the standard JLabel???
one aligned to the left, and another to the right. To the left of what??? To the right of what???
I need that the panel containing the two use all the available
space in the left part of the Split panel.Panel containing the two what??? I thought the left part of the SplitPanel contained a JTree??? -
JTree problems (getting urgent)
A screen prototype that I am writing uses a JTree and a JList.
Whenever the JTree is Expanded or Colapsed, the list is updated so that is displays:
myJTree.getPathForRow(i).getPathComponent(1);
where i is the row of both the tree and the list.
My problem is that the list is always one stage behind!
ie my JTree is initialised(with root hidden):
Colour
Fruit
Sport
and the list box displays:
Colour
Fruit
Sport
if I expand Colour, the tree displays:
Colour
-Red
-Green
Fruit
Sport
and the list displays:
Colour
Fruit
Sport
then I expand Fruit, the tree displays:
Colour
-Red
-Green
Fruit
-Apple
Sport
the list displays:
Colour
Colour
Colour
Fruit
Sport
etc. etc.
why is this happening?
and how can I change my code so that the list displays what the tree is displaying and not what the tree used to display!This is the update method:
DefaultListModel model = new DefaultListModel();
for(int i = 0; i<myJTree.getRowCount();++i) {
model.addElement(myJTree.getPathForRow(i).getPathComponent(1));
and the JTree expansion listener finds out which frame it is being called from before calling the update method on that frame.
When you say, remove all the items from the list, do you mean remove the previous model? -
before i add a new node to a jtree some nodes r expanded. so after i added the new node in the JTree i want to show the nodes that were previously expanded in the jtree. what is the way?
I am using,
model : DefaultTreeModel
tree : JTree
rootnode : DefaultMutableTreeNode
Now i am calling the model.reload() method. if the user is selected any node in the tree then i add the new node and call the reload, cause the cast cast exception: can't to cast MyObject to TreeNode. why?Thank you very much Steve, I was able to integrate
your code in my own application. It's working fine.
I will do more tests with it and let you know about
it.That's terrific Andre. I am very pleased the code worked and helped you. I hope this solution 'nails' the much wondered about JTree refresh problem once and for all.
Should you come across any bugs, or if you think of any means of improvement during your testing, I would be very interested to hear from you.
In any case, good luck with your project, and all the best,
Steve -
Jtree - Problem creating a very large one
Hi,
I need to create a multi-level JTree that is very large (aroung 600-650 nodes all in all). At present I am doing the same by creating DefaultMutableTreeNodes and adding them one by one to the tree. It takes a very long time to complete(obviously).
Is there any way of doing this faster? The tree is being constructed from run-time data.
Thanks in advance,
Regards,
AchyuthTwo thoughts. First, I create 100's of nodes and it's pretty fast. It could be how you are creating/adding them. Make sure your code is not the bottleneck. If you are traversing the entire tree or some other odd way of doing it, it could be the problem. I only say that because I am able to create an object structre, parse XML as I create that structe and create all the nodes and its less than 1 second on a PIV 1.7Ghz system. Maybe on slower systems its a lot slower, but for me its up immediately.
Another way, however, is to keep a Map of "paths" to child items in memory. As you build your object from whever, use a Map to keep path info. Now, add listeners to the tree for expand/collapse. Each time it is about to expand, build up the nodes and add them to the expanding node at that point. If it collapses, discard them. This does one of two things. First, for large trees, you aren't wasting tons of time building the tree at the start, and more so, its probably likely that all those nodes aren't going to be expanded/shown right away. Second, it conserves resources. If your tree MUST open in a fully epxanded state, well, then you may be out of luck. But I would much prefer epxanding and building the child nodes at that moment, rather than do the whole thing first. -
JTree problem displaying nodes
I have created a GUI, in which part of it allows the user to view files in a selected folder in a JTree format.
The tree only shows selected files with certain extensions (such as ".txt", ".doc", etc.. see code below)
I'll try to show what it looks like, for example:
- RootFolder
- SomeOpenFolder
- someFile
- anotherFile
+ SomeClosedFolder
- File_in_RootFolder
- Another_file_in_RootFolder Anyhow, when I shipped it to my boss he occasionally cannot view the full file names..
for example:
- RootFolder
- SomeOp....
- some....
- anothe...
+ SomeClo...
- File_in_R...
- Another_fil...I have the JTree inside a JScrollPane with horizontalScrollBarPolicy set to "AS_NEEDED"
I have run several tests, with both LONG and SHORT names... and it all works just fine for me
For example:
- RootFolder
- SomeOpenFolder
- someFile
- anotherFile_With_A_VERY_VERY_VERY_VERY_LOOOOOOOOOOOOOOOOOOOONG_NAME
+ SomeClosedFolder_With_A_VERY_VERY_VERY_VERY_LOOOONG_NAME
- File_in_RootFolder
- Another_file_in_RootFolder And i am able to scroll left&right to view the full name within the scroll panel.
But for some reason, on my Bosses computer sometimes it has the full name,
and other times it cuts the name short with "FolderNa..."
Is anyone aware of why such a problem could happen?
Here is my code setting up the tree.
public void setMyTree(String myFolder)
File rootFile = new File(myFolder);
JTree targetTree = new JTree(TreeSetup(rootFile, InputIncludeFilter()));
targetTree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
targetTree.setCellRenderer(new TreeCellRenderer() {
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
JLabel label = new JLabel(value.toString());
TreePath p = tree.getPathForRow(row);
if(p != null){
File node = getInputFile(p);
if (selected) {
label.setOpaque(true);
label.setBackground(tree.getBackground().darker());
return label;
private File getInputFile(TreePath path) {
StringBuffer fName = new StringBuffer();
boolean isroot = true;
for (Object s : path.getPath()) {
fName.append(s + File.separator);
return new File(getUserDomain()+File.separator +
fName.toString().substring(0, fName.toString().length() - 1));
}Any ideas? Do would it help to see my method "InputIncludeFilter()"DefaultTreeCellRenderer extends from JLabel, so whatever you are doing to the JLabel you create you can do to the DefaultTreeCellRenderer too.
This would be more like it:
targetTree.setCellRenderer(new DefaultTreeCellRenderer() {
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus)
super.getTreeCellRendererComponent(tree,value,selected,expanded,leaf,row,hasFocus);
TreePath p = tree.getPathForRow(row);
if(p != null){
File node = getInputFile(p);
if (selected) {
this.setOpaque(true);
this.setBackground(tree.getBackground().darker());
return this;
} -
I posted a simillar problem not long ago but didn't explain properly.
The code below displays a JFrame with a JScrollPane containing a JTree with just a root node ("root").
At the bottom of the frame is a button that when pressed re-initialises the JTree with no arguments (line 42). Hence once the button is clicked the JTree should have some elements in it (those default ones : colours, sports, food).
However, the reinitialised JTree is not displayed. What's the problem?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
class Test extends JFrame implements ActionListener {
private JScrollPane treeScrollPane;
private JTree tree;
private DefaultMutableTreeNode root;
private JButton runButton;
public Test() {
super("Test");
this.tree = new JTree(this.root = new DefaultMutableTreeNode("root"));
this.treeScrollPane = new JScrollPane(new JTree());
this.treeScrollPane.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Tree panel"),
BorderFactory.createEmptyBorder(5,5,5,5)));
this.runButton = new JButton("click me");
this.runButton.addActionListener(this);
Container contentPane = getContentPane();
contentPane.setLayout(new BorderLayout());
contentPane.add(this.treeScrollPane, BorderLayout.CENTER);
contentPane.add(this.runButton, BorderLayout.SOUTH);
this.setSize(300, 400);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source == this.runButton) {
System.out.println("DEBUG : button clicked");
this.tree = new JTree();
this.tree.expandPath(new TreePath(this.tree.getModel().getRoot()));
public static void main(String args[]) {
try {
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
System.out.println(e.getMessage());
new Test();
}The problem is that the scrollpane is still displaying the first tree.
To fix this, you'll need to add the following line to your actionPerformed method:
treeScrollPane.setViewportView(tree);(I think you might be a litle confused by the difference between an object and a reference. The scrollpane holds a reference to the first tree you create. Then you create a new tree and assign it to your this.tree reference, but the scrollpane's reference is stil pointing to the first tree. If this explanation is all mumbled up it's because I haven't had my first cup of coffee yet :-) -
Deat 7rst,
Sorry, I want to ask you about the same problem.
if I want to display a difference components from difference node in JTree, how the code I must use?
I already understand about the code that you give to me. But I still confuse if many nodes in JTree to perform difference panel with many components each of its. The components beside JTextField.
ThanksI have used THE SEARCH BOX - can't find nothing about editable JList, there are only references for editable Trees and Tables.
Do anybody have concrete idea (the best would be some code), or should I reconcile myself with the JTable solution?
Maybe you are looking for
-
How do I delete a file from a directory
I want to delete the file I have finished processing in the c:\upload directory but the f.delete() command is not working. Am I using this command correctly? The f.delete() is after I copy the file to an archive directory. Program: import java.io.*;
-
How do I transfer Libraries from one computer to the other?
ok i know this might sound like a dumb question but i have no idea how to do it how do i? i downloaded another library onto this computer but it wouldnt transfer any of my songs so how do i transfer libraries??
-
Using Time Machine to back up to a Windows 2003 Server
I am trying to set up my Time Machine to back up to a windows 2003 server share. I have found some hacks on how to do so, however i am not successful. What I have done so far: TMShowUnsupportedNetworkVolumes 1 in terminal, which got TM to see my shar
-
FF 28.0a1....I can open tabs in Win XP and close them with no problems. In Win 7 I can open tabs but cannot close them until i shut down FF completely. I have completely uninstalled FF28.0a1 and reinstalled it into a new folder with a new profile. St
-
Library management with external hard drive
I have a 120GB external hard drive, where I store all of my music, audiobooks, videos, etc. When I created my iTunes library, everything worked great and I loaded my media into my Video iPod. But, the next time I plugged my external hard drive into m