LookAndFeel in JTree

Hi All,
i have a small problem in LookAndFeel for my Tree. in our project we are using JDK1.1.7B and Swing1.0..It is a client requirement..Is it possible to cretae my tree like windows Explorer..i am not geting tree structure..just i am geting bullets for tree and subtree , I am not geting link to leaf nodes from subtree and link from main leafs to main root...why..i used
public static String windowsUI = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
try {
UIManager.setLookAndFeel(windowsUI);
UIDefaults def = UIManager.getDefaults();
for (Enumeration e = def.keys(); e.hasMoreElements();)
{ String key = (String)e.nextElement();
System.out.println(key+ ":"+def.get(key));
}catch (Exception ex)
System.out.println(ex);
..........and i tried this also
try{
UIManager.setInstalledLookAndFeels(UIManager.getInstalledLookAndFeels());
}catch(Exception e){System.out.println("Exception "+e);}
but i am geting exception like this
Exception occurred during event dispatching:
java.lang.NoSuchMethodError: com.sun.java.swing.plaf.windows.WindowsTreeUI$Expan
dedIcon: method createExpandedIcon()Lcom/sun/java/swing/Icon; not found
at
at com.sun.java.swing.UIDefaults.get(Compiled Code)
at com.sun.java.swing.MultiUIDefaults.get(Compiled Code)
at PopLayersCompHashAllTree.popupLayers(Compiled Code)
at PopLayersCompHashAllTree.<init>(PopLayersCompHashAllTree.java:38)
at MapSketchDelAll.actionPerformed(MapSketchDelAll.java:217)
at com.sun.java.swing.AbstractButton.fireActionPerformed(Compiled Code)
at com.sun.java.swing.AbstractButton$ForwardActionEvents.actionPerformed
(AbstractButton.java:924)
at com.sun.java.swing.DefaultButtonModel.fireActionPerformed(Compiled Co
de)
at com.sun.java.swing.DefaultButtonModel.setPressed(DefaultButtonModel.j
ava:230)
at com.sun.java.swing.plaf.basic.BasicButtonListener.mouseReleased(Basic
ButtonListener.java:191)
at java.awt.Component.processMouseEvent(Component.java:2354)
at java.awt.Component.processEvent(Compiled Code)
at java.awt.Container.processEvent(Compiled Code)
at java.awt.Component.dispatchEventImpl(Compiled Code)
at java.awt.Container.dispatchEventImpl(Compiled Code)
at java.awt.Component.dispatchEvent(Compiled Code)
at java.awt.LightweightDispatcher.retargetMouseEvent(Compiled Code)
at java.awt.LightweightDispatcher.processMouseEvent(Compiled Code)
at java.awt.LightweightDispatcher.dispatchEvent(Compiled Code)
at java.awt.Container.dispatchEventImpl(Compiled Code)
at java.awt.Window.dispatchEventImpl(Compiled Code)
at java.awt.Component.dispatchEvent(Compiled Code)
at java.awt.EventDispatchThread.run(Compiled Code)

This bug is fixed in 1.5 and there is a workaround available for 1.4.2. See bug report:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4887931

Similar Messages

  • Problem in LookAndFeel(..JTree..)

    Hi All,
    i have a small problem in LookAndFeel for my Tree. in our project we are using JDK1.1.7B and Swing1.0..It is a client requirement..Is it possible to cretae my tree like windows Explorer..i am not geting tree structure..just i am geting bullets for tree and subtree , I am not geting link to leaf nodes from subtree and link from main leafs to main root...why..i used
    public static String windowsUI = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
    try {
    UIManager.setLookAndFeel(windowsUI);
    UIDefaults def = UIManager.getDefaults();
    for (Enumeration e = def.keys(); e.hasMoreElements();)
    { String key = (String)e.nextElement();
    System.out.println(key+ ":"+def.get(key));
    }catch (Exception ex)
    System.out.println(ex);
    ..........and i tried this also
    try{
    UIManager.setInstalledLookAndFeels(UIManager.getInstalledLookAndFeels());
    }catch(Exception e){System.out.println("Exception "+e);}
    but i am geting exception like this
    Exception occurred during event dispatching:
    java.lang.NoSuchMethodError: com.sun.java.swing.plaf.windows.WindowsTreeUI$Expan
    dedIcon: method createExpandedIcon()Lcom/sun/java/swing/Icon; not found
    at
    at com.sun.java.swing.UIDefaults.get(Compiled Code)
    at com.sun.java.swing.MultiUIDefaults.get(Compiled Code)
    at PopLayersCompHashAllTree.popupLayers(Compiled Code)
    at PopLayersCompHashAllTree.<init>(PopLayersCompHashAllTree.java:38)
    at MapSketchDelAll.actionPerformed(MapSketchDelAll.java:217)
    at com.sun.java.swing.AbstractButton.fireActionPerformed(Compiled Code)
    at com.sun.java.swing.AbstractButton$ForwardActionEvents.actionPerformed
    (AbstractButton.java:924)
    at com.sun.java.swing.DefaultButtonModel.fireActionPerformed(Compiled Co
    de)
    at com.sun.java.swing.DefaultButtonModel.setPressed(DefaultButtonModel.j
    ava:230)
    at com.sun.java.swing.plaf.basic.BasicButtonListener.mouseReleased(Basic
    ButtonListener.java:191)
    at java.awt.Component.processMouseEvent(Component.java:2354)
    at java.awt.Component.processEvent(Compiled Code)
    at java.awt.Container.processEvent(Compiled Code)
    at java.awt.Component.dispatchEventImpl(Compiled Code)
    at java.awt.Container.dispatchEventImpl(Compiled Code)
    at java.awt.Component.dispatchEvent(Compiled Code)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Compiled Code)
    at java.awt.LightweightDispatcher.processMouseEvent(Compiled Code)
    at java.awt.LightweightDispatcher.dispatchEvent(Compiled Code)
    at java.awt.Container.dispatchEventImpl(Compiled Code)
    at java.awt.Window.dispatchEventImpl(Compiled Code)
    at java.awt.Component.dispatchEvent(Compiled Code)
    at java.awt.EventDispatchThread.run(Compiled Code)
    Thanks in Advance,
    Regards
    Akula

    hi sir ,
    thaks for u'r suggession.Its working fine but the
    properties of the previous tree were not working
    after setModel() property .like action at leaf node
    is not working,I'm sorry but I don't understand. I think you are saying that the problem is solved but I can read it to mean that you still have a problem.
    If you still have a problem then please post some code (using the [code] tags of course).

  • JTree custom renderer setting selection background color problem

    Hi,
    I have a JTree with a custom icon renderer that displays an icon. The JTree is part of a TreeTable component. Iam having a problem setting the selection background uniformly for the entire row. There is no problem when there is no row selected in the JTable.
    My present code looks like this:
    Iam overriding paint in my renderer which extends DefaultCellRenderer.
           super.paint(g);
            Color bColor = null;
            if(!m_selected) {
                 if(currRow % 2 == 0) {
                      bColor = Color.WHITE;
                 } else {
                                                    bColor = backColor;
            } else {
                 bColor = table.getSelectionBackground();                  bColor = getRowSelectionColor();
         if(bColor != null) {
                           g.setColor(bColor);
             if(!m_selected) {
                   g.setXORMode(new Color(0xFF, 0xFF, 0xFF));
             } else {
                 g.setXORMode(new Color(0x00, 0x00, 0x00));
                  I have a color I arrive at using some algorithm that I want using method getRowSelectionColor(). The other cells in the row have this color. But the cell containing the tree node shows different color. Iam not able to arrive at the right combination of the color to set and the xor color so my tree node also looks like the other cells in the row.
    It is not a problem really as the table still looks good. Its just that the tree node looks like it has been highlighted and this might cause a problem when a table cell is highlighed later on in the application ( two cells in the row would be highlighted causing confusion).
    Any help would be appreciated.
    Regards,
    vidyut

    Hi Camickr,
    Thanks for the reply. Iam sorry I didn't include the sources the first time around. There were too many of them. I have created a small, self-contained, compilable program that demonstrates the problem and including it herewith. Still there's quite many files but they are all needed Iam afraid. The only one you will have to concern yourself fior this problem is the file IconRenderer.java. The treenode background and the other cells background are not in sync when table row is not selected in this example though. But they are in my real program. I just need them to be in sync i.e have the same background color when the row is selected.
    Your help would be very much appreciated.
    These are the files that are included below:
    1. AbstractTreeTableModel.java
    2. Bookmarks.java
    3. BookmarksModel.java
    4. DynamicTreeTableModel.java
    5. IconRenderer.java
    6. IndicatorRenderer.java
    7. JTreeTable.java
    8. TreeTableExample3.java (contains main)
    9. TreeTableModel.java
    10. TreeTableModelAdapter.java
    The copyright and javadocs information has been stripped for clarity.
    cheers,
    vidyut
    // AbstractTreeTableModel.java BEGIN
    import javax.swing.tree.*;
    import javax.swing.event.*;
    public abstract class AbstractTreeTableModel implements TreeTableModel {
        protected Object root;    
        protected EventListenerList listenerList = new EventListenerList();
        public AbstractTreeTableModel(Object root) {
            this.root = root;
        // Default implementations for methods in the TreeModel interface.
        public Object getRoot() {
            return root;
        public boolean isLeaf(Object node) {
            return getChildCount(node) == 0;
        public void valueForPathChanged(TreePath path, Object newValue) {}
        // This is not called in the JTree's default mode:
        // use a naive implementation.
        public int getIndexOfChild(Object parent, Object child) {
            for (int i = 0; i < getChildCount(parent); i++) {
             if (getChild(parent, i).equals(child)) {
                 return i;
         return -1;
        public void addTreeModelListener(TreeModelListener l) {
            listenerList.add(TreeModelListener.class, l);
        public void removeTreeModelListener(TreeModelListener l) {
            listenerList.remove(TreeModelListener.class, l);
        protected void fireTreeNodesChanged(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]).treeNodesChanged(e);
    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[i]==TreeModelListener.class) {
    // Lazily create the event:
    if (e == null)
    e = new TreeModelEvent(source, path,
    childIndices, children);
    ((TreeModelListener)listeners[i+1]).treeNodesInserted(e);
    protected void fireTreeNodesRemoved(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[i]==TreeModelListener.class) {
    // Lazily create the event:
    if (e == null)
    e = new TreeModelEvent(source, path,
    childIndices, children);
    ((TreeModelListener)listeners[i+1]).treeNodesRemoved(e);
    protected void fireTreeStructureChanged(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[i]==TreeModelListener.class) {
    // Lazily create the event:
    if (e == null)
    e = new TreeModelEvent(source, path,
    childIndices, children);
    ((TreeModelListener)listeners[i+1]).treeStructureChanged(e);
    // Default impelmentations for methods in the TreeTableModel interface.
    public Class getColumnClass(int column) { return Object.class; }
    public boolean isCellEditable(Object node, int column) {
    return getColumnClass(column) == TreeTableModel.class;
    public void setValueAt(Object aValue, Object node, int column) {}
    // Left to be implemented in the subclass:
    * public Object getChild(Object parent, int index)
    * public int getChildCount(Object parent)
    * public int getColumnCount()
    * public String getColumnName(Object node, int column)
    * public Object getValueAt(Object node, int column)
    // AbstractTreeTableModel.java END
    // Bookmarks.java BEGIN
    import java.io.*;
    import java.net.*;
    import java.util.*;
    import javax.swing.*;
    import javax.swing.tree.*;
    import javax.swing.text.*;
    import javax.swing.text.html.*;
    import javax.swing.text.html.parser.*;
    public class Bookmarks {
    /** The root node the bookmarks are added to. */
    private BookmarkDirectory root;
    * Creates a new Bookmarks object, with the entries coming from
    * <code>path</code>.
    public Bookmarks(String path) {
         root = new BookmarkDirectory("Bookmarks");
         if (path != null) {
         parse(path);
    * Returns the root of the bookmarks.
    public BookmarkDirectory getRoot() {
         return root;
    protected void parse(String path) {
         try {
         BufferedReader reader = new BufferedReader(new FileReader
                                       (path));
         new ParserDelegator().parse(reader, new CallbackHandler(), true);
         catch (IOException ioe) {
         System.out.println("IOE: " + ioe);
         JOptionPane.showMessageDialog(null, "Load Bookmarks",
                             "Unable to load bookmarks",
                             JOptionPane.ERROR_MESSAGE);
    private static final short NO_ENTRY = 0;
    private static final short BOOKMARK_ENTRY = 2;
    private static final short DIRECTORY_ENTRY = 3;
    private class CallbackHandler extends HTMLEditorKit.ParserCallback {
         /** Parent node that new entries are added to. */
         private BookmarkDirectory parent;
         /** The most recently parsed tag. */
         private HTML.Tag tag;
         /** The last tag encountered. */
         private HTML.Tag lastTag;
         * The state, will be one of NO_ENTRY, DIRECTORY_ENTRY,
    * or BOOKMARK_ENTRY.
         private short state;
         * Date for the next BookmarkDirectory node.
         private Date parentDate;
         * The values from the attributes are placed in here. When the
         * text is encountered this is added to the node hierarchy and a
    * new instance is created.
         private BookmarkEntry lastBookmark;
         * Creates the CallbackHandler.
         public CallbackHandler() {
         parent = root;
         lastBookmark = new BookmarkEntry();
         // HTMLEditorKit.ParserCallback methods
         * Invoked when text in the html document is encountered. Based on
         * the current state, this will either: do nothing
    * (state == NO_ENTRY),
         * create a new BookmarkEntry (state == BOOKMARK_ENTRY) or
    * create a new
         * BookmarkDirectory (state == DIRECTORY_ENTRY). If state is
    * != NO_ENTRY, it is reset to NO_ENTRY after this is
    * invoked.
    public void handleText(char[] data, int pos) {
         switch (state) {
         case NO_ENTRY:
              break;
         case BOOKMARK_ENTRY:
              // URL.
              lastBookmark.setName(new String(data));
    parent.add(lastBookmark);
    lastBookmark = new BookmarkEntry();
              break;
         case DIRECTORY_ENTRY:
              // directory.
              BookmarkDirectory newParent = new
                   BookmarkDirectory(new String(data));
              newParent.setCreated(parentDate);
              parent.add(newParent);
              parent = newParent;
              break;
         default:
              break;
    state = NO_ENTRY;
         * Invoked when a start tag is encountered. Based on the tag
         * this may update the BookmarkEntry and state, or update the
         * parentDate.
         public void handleStartTag(HTML.Tag t, MutableAttributeSet a,
                        int pos) {
         lastTag = tag;
         tag = t;
         if (t == HTML.Tag.A && lastTag == HTML.Tag.DT) {
    long lDate;
              // URL
              URL url;
              try {
              url = new URL((String)a.getAttribute(HTML.Attribute.HREF));
              } catch (MalformedURLException murle) {
              url = null;
              lastBookmark.setLocation(url);
              // created
              Date date;
              try {
    lDate = Long.parseLong((String)a.getAttribute("add_date"));
    if (lDate != 0l) {
    date = new Date(1000l * lDate);
    else {
    date = null;
              } catch (Exception ex) {
              date = null;
              lastBookmark.setCreated(date);
              // last visited
              try {
    lDate = Long.parseLong((String)a.
    getAttribute("last_visit"));
    if (lDate != 0l) {
    date = new Date(1000l * lDate);
    else {
    date = null;
              } catch (Exception ex) {
              date = null;
              lastBookmark.setLastVisited(date);
              state = BOOKMARK_ENTRY;
         else if (t == HTML.Tag.H3 && lastTag == HTML.Tag.DT) {
              // new node.
              try {
              parentDate = new Date(1000l * Long.parseLong((String)a.
                                  getAttribute("add_date")));
              } catch (Exception ex) {
              parentDate = null;
              state = DIRECTORY_ENTRY;
         * Invoked when the end of a tag is encountered. If the tag is
         * a DL, this will set the node that parents are added to the current
         * nodes parent.
         public void handleEndTag(HTML.Tag t, int pos) {
         if (t == HTML.Tag.DL && parent != null) {
              parent = (BookmarkDirectory)parent.getParent();
    public static class BookmarkDirectory extends DefaultMutableTreeNode {
         /** Dates created. */
         private Date created;
         public BookmarkDirectory(String name) {
         super(name);
         public void setName(String name) {
         setUserObject(name);
         public String getName() {
         return (String)getUserObject();
         public void setCreated(Date date) {
         this.created = date;
         public Date getCreated() {
         return created;
    public static class BookmarkEntry extends DefaultMutableTreeNode {
         /** User description of the string. */
         private String name;
         /** The URL the bookmark represents. */
         private URL location;
         /** Dates the URL was last visited. */
         private Date lastVisited;
         /** Date the URL was created. */
         private Date created;
         public void setName(String name) {
         this.name = name;
         public String getName() {
         return name;
         public void setLocation(URL location) {
         this.location = location;
         public URL getLocation() {
         return location;
         public void setLastVisited(Date date) {
         lastVisited = date;
         public Date getLastVisited() {
         return lastVisited;
         public void setCreated(Date date) {
         this.created = date;
         public Date getCreated() {
         return created;
         public String toString() {
         return getName();
    // Bookmarks.java END
    // BookmarksModel.java BEGIN
    import java.util.Date;
    public class BookmarksModel extends DynamicTreeTableModel {
    * Names of the columns.
    private static final String[] columnNames =
    { "Name", "Location", "Last Visited", "Created" };
    * Method names used to access the data to display.
    private static final String[] methodNames =
    { "getName", "getLocation", "getLastVisited","getCreated" };
    * Method names used to set the data.
    private static final String[] setterMethodNames =
    { "setName", "setLocation", "setLastVisited","setCreated" };
    private static final Class[] classes =
    { TreeTableModel.class, String.class, Date.class, Date.class };
    public BookmarksModel(Bookmarks.BookmarkDirectory root) {
         super(root, columnNames, methodNames, setterMethodNames, classes);
    public boolean isCellEditable(Object node, int column) {
         switch (column) {
         case 0:
         // Allow editing of the name, as long as not the root.
         return (node != getRoot());
         case 1:
         // Allow editing of the location, as long as not a
         // directory
         return (node instanceof Bookmarks.BookmarkEntry);
         default:
         // Don't allow editing of the date fields.
         return false;
    // BookmarksModel.java END
    // DynamicTreeTableModel.java BEGIN
    import java.lang.reflect.*;
    import javax.swing.tree.*;
    public class DynamicTreeTableModel extends AbstractTreeTableModel {
    /** Names of the columns, used for the TableModel getColumnName method. */
    private String[] columnNames;
    private String[] methodNames;
    private String[] setterMethodNames;
    /** Column classes, used for the TableModel method getColumnClass. */
    private Class[] cTypes;
    public DynamicTreeTableModel(TreeNode root, String[] columnNames,
                        String[] getterMethodNames,
                        String[] setterMethodNames,
                        Class[] cTypes) {
         super(root);
         this.columnNames = columnNames;
         this.methodNames = getterMethodNames;
         this.setterMethodNames = setterMethodNames;
         this.cTypes = cTypes;
    public int getChildCount(Object node) {
         return ((TreeNode)node).getChildCount();
    public Object getChild(Object node, int i) {
         return ((TreeNode)node).getChildAt(i);
    public boolean isLeaf(Object node) {
         return ((TreeNode)node).isLeaf();
    public int getColumnCount() {
         return columnNames.length;
    public String getColumnName(int column) {
         if (cTypes == null || column < 0 || column >= cTypes.length) {
         return null;
         return columnNames[column];
    public Class getColumnClass(int column) {
         if (cTypes == null || column < 0 || column >= cTypes.length) {
         return null;
         return cTypes[column];
    public Object getValueAt(Object node, int column) {
         try {
         Method method = node.getClass().getMethod(methodNames[column],
                                  null);
         if (method != null) {
              return method.invoke(node, null);
         catch (Throwable th) {}
         return null;
    * Returns true if there is a setter method name for column
    * <code>column</code>. This is set in the constructor.
    public boolean isCellEditable(Object node, int column) {
    return (setterMethodNames != null &&
         setterMethodNames[column] != null);
    // Note: This looks up the methods each time! This is rather inefficient;
    // it should really be changed to cache matching
    // methods/constructors
    // based on <code>node</code>'s class, and code>aValue</code>'s
    //class.
    public void setValueAt(Object aValue, Object node, int column) {
         boolean found = false;
         try {
         // We have to search through all the methods since the
         // types may not match up.
         Method[] methods = node.getClass().getMethods();
         for (int counter = methods.length - 1; counter >= 0; counter--) {
              if (methods[counter].getName().equals
              (setterMethodNames[column]) && methods[counter].
              getParameterTypes() != null && methods[counter].
              getParameterTypes().length == 1) {
              // We found a matching method
              Class param = methods[counter].getParameterTypes()[0];
              if (!param.isInstance(aValue)) {
                   // Yes, we can use the value passed in directly,
                   // no coercision is necessary!
                   if (aValue instanceof String &&
                   ((String)aValue).length() == 0) {
                   // Assume an empty string is null, this is
                   // probably bogus for here.
                   aValue = null;
                   else {
                   // Have to attempt some sort of coercision.
                   // See if the expected parameter type has
                   // a constructor that takes a String.
                   Constructor cs = param.getConstructor
                   (new Class[] { String.class });
                   if (cs != null) {
                        aValue = cs.newInstance(new Object[]
                                       { aValue });
                   else {
                        aValue = null;
              // null either means it was an empty string, or there
              // was no translation. Could potentially deal with these
              // differently.
              methods[counter].invoke(node, new Object[] { aValue });
              found = true;
              break;
         } catch (Throwable th) {
         System.out.println("exception: " + th);
         if (found) {
         // The value changed, fire an event to notify listeners.
         TreeNode parent = ((TreeNode)node).getParent();
         fireTreeNodesChanged(this, getPathToRoot(parent),
                        new int[] { getIndexOfChild(parent, node) },
                        new Object[] { node });
    public TreeNode[] getPathToRoot(TreeNode aNode) {
    return getPathToRoot(aNode, 0);
    private TreeNode[] getPathToRoot(TreeNode aNode, int depth) {
    TreeNode[] retNodes;
         // This method recurses, traversing towards the root in order
         // size the array. On the way back, it fills in the nodes,
         // starting from the root and working back to the original node.
    /* Check for null, in case someone passed in a null node, or
    they passed in an element that isn't rooted at root. */
    if(aNode == null) {
    if(depth == 0)
    return null;
    else
    retNodes = new TreeNode[depth];
    else {
    depth++;
    if(aNode == root)
    retNodes = new TreeNode[depth];
    else
    retNodes = getPathToRoot(aNode.getParent(), depth);
    retNodes[retNodes.length - depth] = aNode;
    return retNodes;
    // DynamicTreeTableModel.java END
    // IconRenderer.java BEGIN
    import java.awt.*;
    import javax.swing.*;
    import javax.swing.tree.*;
    import javax.swing.plaf.basic.BasicTreeUI;
    class IconRenderer extends DefaultTreeCellRenderer
    // Color backColor = new Color(0xD0, 0xCC, 0xFF);
    Color backColor = new Color(0xF0, 0xF0, 0xE0);
    String tipText = "";
    JTree tree;
    int currRow = 0;
    boolean m_selected;
    JTable table;
    public IconRenderer(JTree tree, JTable table) {
    this.table = table;
    // setBackground(backColor);
    setBackground(Color.GREEN);
    setForeground(Color.black);
         this.tree = tree;
    public Component getTreeCellRendererComponent(JTree tree, Object value,
    boolean selected,
    boolean expanded, boolean leaf,
    int row, boolean hasFocus) {
         Object node = null;
         super.getTreeCellRendererComponent(
    tree, value, selected,
    expanded, leaf, row,
    hasFocus);
         TreePath treePath = tree.getPathForRow(row);
    if(treePath != null)
              node = treePath.getLastPathComponent();
    currRow = row;
    m_selected = selected;
    DefaultMutableTreeNode itc = null;
    if (node instanceof DefaultMutableTreeNode) {
    itc = (DefaultMutableTreeNode)node;
         setClosedIcon(closedIcon);
    setOpenIcon(openIcon);
    return this;
    /* Override the default to send back different strings for folders and leaves. */
    public String getToolTipText() {
    return tipText;
    * Paints the value. The background is filled based on selected.
    public void paint(Graphics g) {
         super.paint(g);
         Color bColor = null;
         if(!m_selected) {
              System.out.println(" iconren not sel currRow " + currRow);
              if(currRow % 2 == 0) {
                   bColor = Color.WHITE;
              } else {
              bColor = backColor;
         } else {
              bColor = table.getSelectionBackground();
              System.out.println("in else selbg = " + bColor);           
              bColor = new Color(0xF0, 0xCC, 0x92);
              System.out.println(" bColor aft = " + bColor);           
         int imageOffset = -1;
         if(bColor != null) {
         imageOffset = getLabelStart();
         g.setColor(bColor);
         if(!m_selected) {
              System.out.println(" not sel setting white ");
              g.setXORMode(new Color(0xFF, 0xFF, 0xFF));
         } else {
    //          g.setXORMode(new Color(0xCC, 0xCC, 0x9F));
              g.setXORMode(new Color(0x00, 0x00, 0x00));
              System.out.println(" using color = " + g.getColor());           
         if(getComponentOrientation().isLeftToRight()) {
         g.fillRect(imageOffset, 0, getWidth() - 1 - imageOffset,
                   getHeight());
         } else {
         g.fillRect(0, 0, getWidth() - 1 - imageOffset,
                   getHeight());
    private int getLabelStart() {
         Icon currentI = getIcon();
         if(currentI != null && getText() != null) {
         return currentI.getIconWidth() + Math.max(0, getIconTextGap() - 1);
         return 0;
    // IconRenderer.java END
    // IndicatorRenderer.java BEGIN
    // import java.awt.*;
    import javax.swing.*;
    import javax.swing.border.*;
    import javax.swing.event.*;
    import javax.swing.tree.*;
    import javax.swing.table.*;
    import javax.swing.table.*;
    import javax.swing.plaf.basic.*;
    import java.awt.event.*;
    import java.util.EventObject;
    import java.text.NumberFormat;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.StringTokenizer;
    import java.util.Arrays;
    class IndicatorRenderer extends DefaultTableCellRenderer {
    /** Makes sure the number of displayed in an internationalized
    * manner. */
    protected NumberFormat formatter;
    /** Row that is currently being painted. */
    protected int lastRow;
    protected int reloadRow;
    protected int reloadCounter;
    protected TreeTableModel treeTableModel;
    protected TreeTableModelAdapter treeTblAdapter;
    protected JTable table;
    Component renderer = null;
    Color backColor = new Color(0xF0, 0xF0, 0xE0);
    IndicatorRenderer(TreeTableModelAdapter treeTblAdapter, TreeTableModel treeTableModel) {
         setHorizontalAlignment(JLabel.RIGHT);
         setFont(new Font("serif", Font.BOLD, 12));
         this.treeTableModel = treeTableModel;
         this.treeTblAdapter = treeTblAdapter;
    * Invoked as part of DefaultTableCellRenderers implemention. Sets
    * the text of the label.
    public void setValue(Object value) {
    /* setText((value == null) ? "---" : formatter.format(value)); */
         setText((value == null) ? "---" : (String) value.toString());
    * Returns this.
    public Component getTableCellRendererComponent(JTable table,
    Object value, boolean isSelected, boolean hasFocus,
    int row, int column) {
         renderer = super.getTableCellRendererComponent(table, value, isSelected,
    hasFocus, row, column);
         lastRow = row;
         this.table = table;
              if(isSelected) {
                   doMask(hasFocus, isSelected);
              } else
              setBackground(table.getBackground());
    return renderer;
    * If the row being painted is also being reloaded this will draw
    * a little indicator.
    public void paint(Graphics g) {
         super.paint(g);
    private void doMask(boolean hasFocus, boolean selected) {
              maskBackground(hasFocus, selected);
    private void maskBackground(boolean hasFocus, boolean selected) {
              Color seed = null;
              seed = table.getSelectionBackground();
              Color color = seed;
              if (color != null) {
                   setBackground(
    new Color(0xF0, 0xCC, 0x92));
    // IndicatorRenderer.java END
    // JTreeTable.java BEGIN
    import java.awt.*;
    import javax.swing.*;
    import javax.swing.border.*;
    import javax.swing.event.*;
    import javax.swing.tree.*;
    import javax.swing.table.*;
    import java.awt.event.*;
    import java.util.EventObject;
    public class JTreeTable extends JTable {
    /** A subclass of JTree. */
    protected TreeTableCellRenderer tree;
    protected IndicatorRenderer indicatorRenderer = null;
    public JTreeTable(TreeTableModel treeTableModel) {
         super();
         // Creates the tree. It will be used as a renderer and editor.
         tree = new TreeTableCellRenderer(treeTableModel);
         TreeTableModelAdapter tdap = new TreeTableModelAdapter(treeTableModel, tree);
         // Installs a tableModel representing the visible rows in the tree.
         super.setModel(tdap);
         // Forces the JTable and JTree to share their row selection models.
         ListToTreeSelectionModelWrapper selectionWrapper = new
         ListToTreeSelectionModelWrapper();
         tree.setSelectionModel(selectionWrapper);
         setSelectionModel(selectionWrapper.getListSelectionModel());
         // Installs the tree editor renderer and editor.
         setDefaultRenderer(TreeTableModel.class, tree);
         setDefaultEditor(TreeTableModel.class, new TreeTableCellEditor());
         indicatorRenderer = new IndicatorRenderer(tdap, treeTableModel);     
         // No grid.
         setShowGrid(false);
         // No intercell spacing
         setIntercellSpacing(new Dimension(0, 0));     
         // And update the height of the trees row to match that of
         // the table.
         //if (tree.getRowHeight() < 1) {
         // Metal looks better like this.
         setRowHeight(20);
    public TableCellRenderer getCellRenderer(int row, int col) {
              if(col == 0)
              return tree;
              else
              return indicatorRenderer;     
    public void updateUI() {
         super.updateUI();
         if(tree != null) {
         tree.updateUI();
         // Do this so that the editor is referencing the current renderer
         // from the tree. The renderer can potentially change each time
         // laf changes.
         setDefaultEditor(TreeTableModel.class, new TreeTableCellEditor());
         // Use the tree's default foreground and background colors in the
         // table.
    LookAndFeel.installColorsAndFont(this, "Tree.background",
    "Tree.foreground", "Tree.font");
    public int getEditingRow() {
    return (getColumnClass(editingColumn) == TreeTableModel.class) ? -1 :
         editingRow;
    private int realEditingRow() {
         return editingRow;
    public void sizeColumnsToFit(int resizingColumn) {
         super.sizeColumnsToFit(resizingColumn);
         if (getEditingColumn() != -1 && getColumnClass(editingColumn) ==
         TreeTableModel.class) {
         Rectangle cellRect = getCellRect(realEditingRow(),
                             getEditingColumn(), false);
    Component component = getEditorComponent();
         component.setBounds(cellRect);
    component.validate();
    public void setRowHeight(int rowHeight) {
    super.setRowHeight(rowHeight);
         if (tree != null && tree.getRowHeight() != rowHeight) {
    tree.setRowHeight(getRowHeight());
    public JTree getTree() {
         return tree;
    public boolean editCellAt(int row, int column, EventObject e){
         boolean retValue = super.editCellAt(row, column, e);
         if (retValue && getColumnClass(column) == TreeTableModel.class) {
         repaint(getCellRect(row, column, false));
         return retValue;
    public class TreeTableCellRenderer extends JTree implements
         TableCellRenderer {
         /** Last table/tree row asked to renderer. */
         protected int visibleRow;
         /** Border to draw around the tree, if this is non-null, it will
         * be painted. */
         protected Border highlightBorder;
         public TreeTableCellRenderer(Tr

  • Where are defined the keybindings for keyboard navigation on a JTree?

    I guess in the JTree.java file but I can't find the line of that tells the JTree to expand a node when you press the + key.

    Do you mean, where is the binding (i.e., the InputMap) created? For the most part, they're generated by the by the LookAndFeel and stored in the UIDefaults table under the keys "FocusInputMap", "AncestorInputMap" and "ComponentInputMap". Most will be found in BasicLookAndFeel.java, but the concrete LnF may override some of them. Also, some UI delegates generate or add to the InputMaps; I know BasicEditorPaneUI does.
    If you want the code for the action itself, it's in BasicTreeUI.java, in the inner class "Actions".

  • JTree expand programatically is not working

    jTree1.fireTreeExpanded(curTreePath);
    expandAll(jTree1, curTreePath, true);
    jTree1.expandPath(curTreePath);
    jTree1.scrollPathToVisible(curTreePath);
    jTree1.updateUI();
    jTree1.setExpandsSelectedPaths(true);
    jTree1.expandPath(curTreePath);
    expandAll(jTree1, curTreePath, true);
    for (int i = 0; i < jTree1.getRowCount(); i++)
    jTree1.expandRow(i);
    jTree1.validate();
    jTree1.repaint();
    Any help ?

    package so;
    ToDo list
    * Log timestamp and line number of at every exception.
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyEvent;
    import java.sql.*;
    import java.io.*;
    import java.net.*;
    import java.util.Enumeration;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.swing.*;
    import javax.swing.event.*;
    import javax.swing.table.*;
    import javax.swing.tree.*;
    public class SCM extends javax.swing.JFrame implements javax.swing.event.TreeExpansionListener, javax.swing.event.TreeModelListener, javax.swing.event.TreeWillExpandListener
        Connection con = null;
        java.sql.Statement stmt = null;
        ResultSet rs = null;
        PrintStream log = null;// File creation at local system, to record events, actions, errors and traces
        javax.swing.tree.TreePath curTreePath = null;
        /** Creates new form SCM */
        public SCM()
            //---------------------- Native LookandFeel Windows is expected.-------------------//
            try
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            catch (Exception e)
                System.out.println("Error setting native LAF: " + e);
            //******************** Native LookandFeel Windows is expected.*******************//
            // initialising GUI containers and controls
            initComponents();
            TableCellRenderer defaultRenderer;
            defaultRenderer = jTable1.getDefaultRenderer(JLabel.class);
            jTable1.setDefaultRenderer(JLabel.class, new Label_cell(defaultRenderer));
            setState(javax.swing.JFrame.HIDE_ON_CLOSE);
            jfc.setEnabled(false);
            this.setSize(1024, 740);
            jTree1.setSize(400, this.getWidth() / 4);
            jTree1.setRootVisible(false);
            jTree1.addTreeWillExpandListener(this); // Registering jTree1 to Expand listener.
            jTree1.setCellRenderer(new TreeIconRenderer());
            try
                //-------Preparing Logger----------------//
                FileOutputStream fos = new FileOutputStream(new File(System.getProperties().getProperty("user.home") + System.getProperties().getProperty("file.separator") + "SCM-Log_" + System.currentTimeMillis()));
                log = new PrintStream(fos);
                log.println("Started Time\t\t:" + new java.util.Date().getTime());
                //*******Preparing Logger****************//
                // Initialising jTree1 with the userid and preparing the xml and loading jTree1 with xml content,
                // and expected to repeat the same while refreshing.
                //----- Rendering images for the folders and files i.e. nodes and leaves of this tree
                jTree1 = new XMLTree("215");
                //******** Rendering images for the folders and files i.e. nodes and leaves of this tree
                //Selection can only contain one path at a time, i.e. user is confined to reffere to only one node
                //or leaf at a time
                //jTree1.getSelectionModel().setSelectionMode(javax.swing.tree.TreeSelectionModel.SINGLE_TREE_SELECTION);
                this.setTitle("ZIIC-ITG SCM");// Title can be changed at any time.
            catch (IOException ioe)
                ioe.printStackTrace(log);   //logging Exception.
                //This is first level action and to be decided to go further or not by exit(0);.
        public boolean prepareCon() throws ClassNotFoundException
            try
                if (con != null && !con.isClosed())
                    return true;
                else
                    Class.forName("oracle.jdbc.driver.OracleDriver");
                    java.sql.DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
                    con = java.sql.DriverManager.getConnection("jdbc:oracle:thin:@172.16.1.31:1521:soadb", "dms", "dms");
                    if (con != null && !con.isClosed())
                        return true;
            catch (java.lang.ClassNotFoundException cnfe)
                cnfe.printStackTrace(log);
            catch (SQLException se)
                se.printStackTrace(log);
            if (con != null)
                return true;
            else
                return true;
        /** This method is called from within the constructor to
         * initialize the form.
         * WARNING: Do NOT modify this code. The content of this method is
         * always regenerated by the Form Editor.
        // <editor-fold defaultstate="collapsed" desc="Generated Code">                         
        private void initComponents()
            jPopupMenu1 = new javax.swing.JPopupMenu();
            jSplitPane1 = new javax.swing.JSplitPane();
            jScrollPane1 = new javax.swing.JScrollPane();
            try
                jTree1 = new XMLTree("215");
                jScrollPane2 = new javax.swing.JScrollPane();
                jTable1 = new javax.swing.JTable();
                menuBar = new javax.swing.JMenuBar();
                fileMenu = new javax.swing.JMenu();
                openMenuItem = new javax.swing.JMenuItem();
                saveMenuItem = new javax.swing.JMenuItem();
                saveAsMenuItem = new javax.swing.JMenuItem();
                exitMenuItem = new javax.swing.JMenuItem();
                editMenu = new javax.swing.JMenu();
                cutMenuItem = new javax.swing.JMenuItem();
                copyMenuItem = new javax.swing.JMenuItem();
                pasteMenuItem = new javax.swing.JMenuItem();
                deleteMenuItem = new javax.swing.JMenuItem();
                helpMenu = new javax.swing.JMenu();
                contentsMenuItem = new javax.swing.JMenuItem();
                aboutMenuItem = new javax.swing.JMenuItem();
                //setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
            }catch(Exception e){}
            jTree1.setDoubleBuffered(true);
            jTree1.setDragEnabled(true);
            jTree1.setEditable(true);
            jTree1.setFocusTraversalPolicyProvider(true);
            jTree1.setInheritsPopupMenu(true);
            jTree1.setInvokesStopCellEditing(true);
            jTree1.setLargeModel(true);
            jTree1.setMaximumSize(new java.awt.Dimension(250, 64));
            jTree1.setPreferredSize(new java.awt.Dimension(200, 64));
            jTree1.setVerifyInputWhenFocusTarget(false);
            jTree1.addMouseListener(new java.awt.event.MouseAdapter()
                public void mouseClicked(java.awt.event.MouseEvent evt)
                    jTree1MouseClicked(evt);
            jTree1.addTreeExpansionListener(new javax.swing.event.TreeExpansionListener()
                public void treeCollapsed(javax.swing.event.TreeExpansionEvent evt)
                    jTree1TreeCollapsed(evt);
                public void treeExpanded(javax.swing.event.TreeExpansionEvent evt)
                    jTree1TreeExpanded(evt);
            jTree1.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener()
                public void valueChanged(javax.swing.event.TreeSelectionEvent evt)
                    jTree1ValueChanged(evt);
            jScrollPane1.setViewportView(jTree1);
            jSplitPane1.setLeftComponent(jScrollPane1);
            jScrollPane2.setAutoscrolls(true);
            jScrollPane2.setDoubleBuffered(true);
            jScrollPane2.setFocusCycleRoot(true);
            jScrollPane2.setFocusTraversalPolicyProvider(true);
            jScrollPane2.setInheritsPopupMenu(true);
            jTable1.setModel(new javax.swing.table.DefaultTableModel(
                new Object [][]
                    {null, null, null, null},
                    {null, null, null, null},
                    {null, null, null, null},
                    {null, null, null, null}
                new String []
                    "Title 1", "Title 2", "Title 3", "Title 4"
            jTable1.addMouseListener(new java.awt.event.MouseAdapter()
                public void mouseClicked(java.awt.event.MouseEvent evt)
                    jTable1MouseClicked(evt);
            jScrollPane2.setViewportView(jTable1);
            jSplitPane1.setRightComponent(jScrollPane2);
            fileMenu.setText("File");
            openMenuItem.setText("Open");
            fileMenu.add(openMenuItem);
            saveMenuItem.setText("Save");
            fileMenu.add(saveMenuItem);
            saveAsMenuItem.setText("Save As ...");
            fileMenu.add(saveAsMenuItem);
            exitMenuItem.setText("Exit");
            exitMenuItem.addActionListener(new java.awt.event.ActionListener()
                public void actionPerformed(java.awt.event.ActionEvent evt)
                    exitMenuItemActionPerformed(evt);
            fileMenu.add(exitMenuItem);
            menuBar.add(fileMenu);
            editMenu.setText("Edit");
            cutMenuItem.setText("Cut");
            editMenu.add(cutMenuItem);
            copyMenuItem.setText("Copy");
            editMenu.add(copyMenuItem);
            pasteMenuItem.setText("Paste");
            editMenu.add(pasteMenuItem);
            deleteMenuItem.setText("Delete");
            editMenu.add(deleteMenuItem);
            menuBar.add(editMenu);
            helpMenu.setText("Help");
            contentsMenuItem.setText("Contents");
            helpMenu.add(contentsMenuItem);
            aboutMenuItem.setText("About");
            helpMenu.add(aboutMenuItem);
            menuBar.add(helpMenu);
            setJMenuBar(menuBar);
            org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
            getContentPane().setLayout(layout);
            layout.setHorizontalGroup(
                layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                .add(layout.createSequentialGroup()
                    .add(jSplitPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 390, Short.MAX_VALUE)
                    .addContainerGap())
            layout.setVerticalGroup(
                layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                .add(layout.createSequentialGroup()
                    .add(jSplitPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 268, Short.MAX_VALUE)
                    .addContainerGap())
            pack();
        }// </editor-fold>                       
        private void jTree1ValueChanged(javax.swing.event.TreeSelectionEvent evt)
        try
            curTreePath = evt.getPath();
            //curTreePath.getPathCount();
            //selectedNode = stPath.getPathComponent(stCount - 1);
            //TODO add your handling code here:
            if (prepareCon())
                javax.swing.tree.TreePath path = evt.getPath();
                DMETreeNode node = (DMETreeNode) path.getLastPathComponent();
                try
                    if (node != null && (node.getSerial() + "").length() > 0)
                        //stmt = con.createStatement();
                        stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
                        rs = stmt.executeQuery("select serial, description, file_location, status, sheet,  part, approvedby, locked, location, created_by from dms_files where owner=" + node.getSerial());
                        SCM_Tbl_model model = new SCM_Tbl_model();
                        model.setRs(rs);
                        //jTable1.setColumnModel(columnModel);
                        jTable1.setModel(model);
                        TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);
                        jTable1.setRowSorter(sorter);
                catch (Exception e)
                    e.printStackTrace();
            catch (ClassNotFoundException ex)
                ex.printStackTrace(log);
                Logger.getLogger(SCM.class.getName()).log(Level.SEVERE, null, ex);
        private void jTree1MouseClicked(java.awt.event.MouseEvent evt)
        // TODO add your handling code here:   
        if (evt.getButton() == evt.BUTTON3)
            jPopupMenu1.removeAll();
            javax.swing.JMenuItem expandMI = new javax.swing.JMenuItem("Expand");
            javax.swing.JMenuItem expandAllMI = new javax.swing.JMenuItem("Expand All");
            javax.swing.JMenuItem find_folderMI = new javax.swing.JMenuItem("Find Folder");
            final javax.swing.JMenuItem new_folderMI = new javax.swing.JMenuItem("New Folder");
            javax.swing.JSeparator separator1 = new javax.swing.JSeparator();
            jPopupMenu1.setSize(100, 200);
            jPopupMenu1.add(expandMI);
            jPopupMenu1.add(expandAllMI);
            jPopupMenu1.add(separator1);
            jPopupMenu1.add(find_folderMI);
            jPopupMenu1.add(new_folderMI);
            jPopupMenu1.setVisible(true);
            jPopupMenu1.show(evt.getComponent(), evt.getX(), evt.getY());
            //expandToLast(jTree1);
            //jTree1.scrollPathToVisible(curTreePath);
            //jTree1.fireTreeExpanded(curTreePath);       
            ActionListener menuOnTree = new ActionListener()
                        public void actionPerformed(ActionEvent e)
                            if (e.getSource().equals(new_folderMI))
                                    DMETreeNode ch=new DMETreeNode("Child of "+((DMETreeNode)curTreePath.getLastPathComponent()).toString());   
                                    ((DMETreeNode) curTreePath.getLastPathComponent()).add(ch);
                                    jTree1.fireTreeExpanded(curTreePath);
                                    expandAll(jTree1, curTreePath, true);
                                    jTree1.expandPath(curTreePath);
                                    jTree1.scrollPathToVisible(curTreePath);
                                    jTree1.updateUI();
                            if (e.getActionCommand().trim().equalsIgnoreCase("Expand"))
                                jTree1.setExpandsSelectedPaths(true);
                                jTree1.expandPath(curTreePath);
                                expandAll(jTree1, curTreePath, true);
                                for (int i = 0; i < jTree1.getRowCount(); i++)
                                    jTree1.expandRow(i);
                                jTree1.validate();
                                jTree1.repaint();
                                System.out.println(((DMETreeNode) curTreePath.getLastPathComponent()).getSerial());
                                expandToLast(jTree1);
                                System.out.println(jTree1.getModel().getRoot().toString());
                                ((XMLTree)jTree1).expandAll(true);
                                expandToLast(jTree1);
            expandMI.addActionListener(menuOnTree);
            expandAllMI.addActionListener(menuOnTree);
            find_folderMI.addActionListener(menuOnTree);
            new_folderMI.addActionListener(menuOnTree);
    public void expandAll(JTree tree, boolean expand)
            TreeNode root = (TreeNode) tree.getModel().getRoot();
            // Traverse tree from root
            expandAll(tree, new TreePath(root), expand);
        private void expandAll(JTree tree, TreePath parent, boolean expand)
            // Traverse children
            TreeNode node = (TreeNode) parent.getLastPathComponent();
            if (node.getChildCount() >= 0)
                for (Enumeration e = node.children(); e.hasMoreElements();)
                    TreeNode n = (TreeNode) e.nextElement();
                    TreePath path = parent.pathByAddingChild(n);
                    //System.out.println(path.toString());
                    expandAll(tree, path, expand);
            // Expansion or collapse must be done bottom-up
            if (expand)
                tree.expandPath(parent);
            else
                tree.collapsePath(parent);
    public void expandToLast(JTree tree)
            // expand to the last leaf from the root
            DefaultMutableTreeNode root;
            root = (DefaultMutableTreeNode) tree.getModel().getRoot();
            tree.scrollPathToVisible(new TreePath(root.getLastLeaf().getPath()));
            //System.out.println(""+root.getLastLeaf().getPath().toString());
        public void expandToLast(JTree tree)
            TreeModel data = tree.getModel();
            Object node = data.getRoot();
            if (node == null)
                return;
            TreePath p = new TreePath(node);
            while (true)
                int count = data.getChildCount(node);
                if (count == 0)
                    break;
                node = data.getChild(node, count - 1);
                p = p.pathByAddingChild(node);
            tree.scrollPathToVisible(p);
        private void jTree1TreeExpanded(javax.swing.event.TreeExpansionEvent evt)
        // TODO add your handling code here:
            System.out.println("@447");
        private void jTree1TreeCollapsed(javax.swing.event.TreeExpansionEvent evt) {                                    
        // TODO add your handling code here:
        private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {                                            
            System.exit(0);
        @SuppressWarnings("static-access")
        private void jTable1MouseClicked(java.awt.event.MouseEvent evt)                                    
            // TODO add your handling code here:
            jPopupMenu1.removeAll();
            jPopupMenu1.setVisible(true);
            //Prepare Menu items based the event and the user, and the item clicked on i.e.
            javax.swing.JMenuItem menuItem = new javax.swing.JMenuItem("Add A doc", KeyEvent.VK_T);
            jPopupMenu1.add(menuItem);
            ActionListener al = new ActionListener()
                        public void actionPerformed(ActionEvent e)
                            jfc.updateUI();
                            jfc.showOpenDialog(jTable1);
                            jTable1.setValueAt(jfc.getSelectedFile().getAbsolutePath(), jTable1.getSelectedRow(), jTable1.getSelectedColumn());
                            jfc.setDialogTitle("Choose only fmx files");
                            try
                                if (jfc.getSelectedFile().getAbsolutePath() != null)
                                    java.io.File f = new java.io.File(jfc.getSelectedFile().getAbsolutePath());
                                    if (f.exists())
                                        // Start FTP process.
                                        SCM_FTP ftp = new SCM_FTP();
                                        ftp.connect("ziicsrv11", 21, "z11902", "ziicit");
                                        ftp.bin();
                                        // Change to a new working directory on the FTP server.
                                        ftp.cwd("bin");
                                        // Upload some files.
                                        log.println("FTP Start: " + System.currentTimeMillis());
                                        ftp.stor(f);
                                        ftp.disconnect();
                                        log.println("FTP Done: " + System.currentTimeMillis());
                            catch (java.io.IOException ioe)
                                log.println("File is not Found");
                                ioe.printStackTrace(log);
            menuItem.addActionListener(al);
            menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_1, ActionEvent.ALT_MASK));
            menuItem.getAccessibleContext().setAccessibleDescription("This doesn't really do anything");
            jPopupMenu1.setSize(100, 200);
            if (evt.getButton() == evt.BUTTON3)//evt.isPopupTrigger()
                jPopupMenu1.show(evt.getComponent(), evt.getX(), evt.getY());
         * @param args the command line arguments
        public static void main(String args[])
            java.awt.EventQueue.invokeLater(new Runnable()
                        public void run()
                            SCM s = new SCM();
                            s.setVisible(true);
                            //s.setState(s.HIDE_ON_CLOSE);
                            s.setAlwaysOnTop(true);
                            SystemTrayTest st = new SystemTrayTest();
                            st.setControl(s);
                            st.showFrame();
        // Variables declaration - do not modify                    
        private javax.swing.JMenuItem aboutMenuItem;
        private javax.swing.JMenuItem contentsMenuItem;
        private javax.swing.JMenuItem copyMenuItem;
        private javax.swing.JMenuItem cutMenuItem;
        private javax.swing.JMenuItem deleteMenuItem;
        private javax.swing.JMenu editMenu;
        private javax.swing.JMenuItem exitMenuItem;
        private javax.swing.JMenu fileMenu;
        private javax.swing.JMenu helpMenu;
        private javax.swing.JPopupMenu jPopupMenu1;
        private javax.swing.JScrollPane jScrollPane1;
        private javax.swing.JScrollPane jScrollPane2;
        private javax.swing.JSplitPane jSplitPane1;
        private javax.swing.JTable jTable1;
        private javax.swing.JTree jTree1;
        private javax.swing.JMenuBar menuBar;
        private javax.swing.JMenuItem openMenuItem;
        private javax.swing.JMenuItem pasteMenuItem;
        private javax.swing.JMenuItem saveAsMenuItem;
        private javax.swing.JMenuItem saveMenuItem;
        // End of variables declaration                  
        private javax.swing.JFileChooser jfc = new javax.swing.JFileChooser();
        public void treeExpanded(TreeExpansionEvent event)
        public void treeCollapsed(TreeExpansionEvent event)
        public void treeNodesChanged(TreeModelEvent e)
        public void treeNodesInserted(TreeModelEvent e)
        public void treeNodesRemoved(TreeModelEvent e)
        public void treeStructureChanged(TreeModelEvent e)
        public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException
        public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException
    }

  • JTree properties

    Hi all!
    I guess this is a simple problem for most of you guys... How to change color of the lines in JTree that connect opened nodes? I guess there must be some property like "JTree.lineColor" because this color changes with changing LookAndFeel. I have read the tutarial and it only says that these properties are in the file <java_install_dir>/lib/swing.properties. But I don't have this file.
    If I find the name of this property, should I set it with UIManager.put(property_name, Color.whatever)?
    Another question:
    is there any way to remove those handles on other nodes not only the root node (with setShowRootHandles)?
    Thanx
    Petar

    For the line use, before creating the tree:
    UIManager.put("Tree.line", Color.red); for example.
    If you want to see all the properties, use this code :
    import java.util.*;
    import javax.swing.*;
    public class UIProperties {
         public static String windowsUI = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
         public static void main(String[] args) {
              try {
              //     UIManager.setLookAndFeel(windowsUI);
                   UIDefaults def = UIManager.getDefaults();
                   for (Enumeration e = def.keys(); e.hasMoreElements();) {
                        String key = (String)e.nextElement();
                        System.out.println(key+ "     :     "+def.get(key));
              catch (Exception ex) {
                   System.out.println(ex);
    }I hope this helps,
    Denis

  • DefaultTreeCellRenderer & LookAndFeel UI

    Hi All,
    I need HELP!!!
    I've found small bug in DefaultTreeCellRenderer Class and Look&Feel UserInterface.
    After use DefaultTreeCellRenderer for JTree, SwingUtilities.updateComponentTreeUI() method can't change UI for initialised JTrees. For new created Trees all work properly.
    The next small Application show this:
    import javax.swing.*;
    import javax.swing.tree.*;
    import javax.swing.UIManager.*;
    import java.awt.*;
    import java.awt.event.*;
    public class TreeRendererBug extends javax.swing.JFrame {
        static private boolean DEBUG = true;
        static private LookAndFeelInfo style[];
        private javax.swing.JMenu myMenuStyle = new javax.swing.JMenu();
        private ButtonGroup groupStyleMenu = new ButtonGroup();
        private javax.swing.JMenuBar jMenuBar1 = new javax.swing.JMenuBar();
        private javax.swing.JMenu jMenu1;
        private javax.swing.JPanel jPanel1 = new javax.swing.JPanel();
        private javax.swing.JScrollPane jScrollPane1 = new javax.swing.JScrollPane();
        private javax.swing.JTree jTree1 = new javax.swing.JTree();
        public TreeRendererBug() {
            try {
                LookAndFeel curStyle=  UIManager.getLookAndFeel();
                style = javax.swing.UIManager.getInstalledLookAndFeels();
                if(style != null) {
                    RadioMenuListener myRadioMenuListener = new RadioMenuListener();
                    for(int ii=0; ii< style.length ;ii++) {
                        if(DEBUG) System.out.println(style[ii].getClassName());
                        JRadioButtonMenuItem jRadioMenuItem = new javax.swing.JRadioButtonMenuItem(style[ii].getName(),style[ii].getName()==curStyle.getName());
                        jRadioMenuItem.setActionCommand(style[ii].getClassName());
                        jRadioMenuItem.addActionListener(myRadioMenuListener);
                        groupStyleMenu.add(jRadioMenuItem);
                        myMenuStyle.add(jRadioMenuItem);
            } catch (Exception e) {
                System.out.println("ERROR: "+e.toString());
            jMenu1 = myMenuStyle;
            jMenu1.setText("UI Style");
            jMenuBar1.add(jMenu1);
            jPanel1.setLayout(new javax.swing.BoxLayout(jPanel1, 0));
            jScrollPane1.setViewportView(jTree1);
            jPanel1.add(jScrollPane1);
            getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER);
            setJMenuBar(jMenuBar1);
            // !!!!!!  Bug in DefaultTreeCellRenderer !!!!!!!!
            // after comment this row, L&F will be set UI style to the all JTree elements
            jTree1.setCellRenderer(new DefaultTreeCellRenderer());
            addWindowListener(new java.awt.event.WindowAdapter() {
                public void windowClosing(java.awt.event.WindowEvent evt) {
                    System.exit (0); }
            pack ();
        public static void main (String args[]) {
            new TreeRendererBug ().show ();
        class RadioMenuListener implements ActionListener {
            public void actionPerformed(ActionEvent e) {
                if(DEBUG) System.out.println("Command "+ e.getActionCommand() );
                try {
                    UIManager.setLookAndFeel(e.getActionCommand());
                    SwingUtilities.updateComponentTreeUI(TreeRendererBug.this);
                    TreeRendererBug.this.validate();
                } catch (Exception exc) {
                    System.out.println("ERROR: "+exc.toString());
    How change UI for initialised JTree with DefaultTreeCellRenderer ?
    Thank you in advance,
    AT.

    Hi All,
    I need HELP!!!
    I've help my self ! :))))
    after change style is it is necessary set new CellRenderer for JTree:
        class RadioMenuListener implements ActionListener {
            public void actionPerformed(ActionEvent e) {
                if(DEBUG) System.out.println("Command "+ e.getActionCommand() );
                try {
                    UIManager.setLookAndFeel(e.getActionCommand());
                    SwingUtilities.updateComponentTreeUI(TreeRendererBug.this);
                    jTree1.setCellRenderer(new DefaultTreeCellRenderer());
                    TreeRendererBug.this.validate();
                } catch (Exception exc) {
                    System.out.println("ERROR: "+exc.toString());
    [//code]                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

  • Different look of button in jtree or jtable (windows/linux)

    Hi.
    I have jbutton on jtree(in jtable is the same problem) it looks like this on linux: http://mikel.pl/button.jpg .
    On windows eveyrthink is ok. I tried to set RaisedBevelBorder but in this case on windows button looks awful. Is any trick to get the same look of button without checking what system is running?

    Yes and no. Linux and Windows use different LookAndFeels by default, meaning the buttons are painted differently. Just setting the same border will not do in this case. The only way of having the application look exactly the same on both platforms is to manually set a LookAndFeel available on both systems. This should be the case for the MetalLookAndFeel, the SynthLookAndFeel and, I believe, for the Linux LookAndFeels as well.

  • JTree XML Viewer

    Hi all
    i found this great article http://www.javalobby.org/java/forums/m91839339.html on Xml Viewer.
    But i dont understand how i can use it for JTreeTable because JTreeTable needs a TreeTableModel but
    i have a XMLTableModel .
    Anyone has used it?
    Thanks!!

    Hi all i try to modify the example that i find to make the tree editable but it not works...
    The main
    import java.awt.Color;
    import java.awt.Component;
    import java.awt.Dimension;
    import java.awt.event.InputEvent;
    import java.awt.event.MouseEvent;
    import java.util.EventObject;
    import javax.swing.JScrollPane;
    public class MyTreeTable extends JTreeTable{
        public MyTreeTable(TreeTableModel treeTableModel){
            super(treeTableModel);
            setShowGrid(true);
            setGridColor(new Color(234, 234, 234));
            new TableColumnResizer(this);
           // setDefaultRenderer(XMLTreeTableModel.class, new  XMLTreeTableCellRenderer());
            setIntercellSpacing(new Dimension(1, 1));
        public boolean editCellAt(int row, int column, EventObject e){
            if(e instanceof MouseEvent){
                MouseEvent me = (MouseEvent)e;
                // If the modifiers are not 0 (or the left mouse button),
                // tree may try and toggle the selection, and table
                // will then try and toggle, resulting in the
                // selection remaining the same. To avoid this, we
                // only dispatch when the modifiers are 0 (or the left mouse
                // button).
                if(me.getModifiers()==0 ||
                        me.getModifiers()==InputEvent.BUTTON1_MASK){
                    for(int counter = getColumnCount()-1; counter>= 0;
                        counter--){
                        if(getColumnClass(counter)==TreeTableModel.class){
                            MouseEvent newME = new MouseEvent
                                    (tree, me.getID(),
                                            me.getWhen(), me.getModifiers(),
                                            me.getX()-getCellRect(0, counter, true).x,
                                            me.getY(), me.getClickCount(),
                                            me.isPopupTrigger());
                            tree.dispatchEvent(newME);
                            break;
                return false;
            return super.editCellAt(row, column, e);
        public void changeSelection(int row, int column, boolean toggle, boolean extend) {
            if(getCursor()==TableColumnResizer.resizeCursor)
                return;
            super.changeSelection(row, column, toggle, extend);
    }The editor
    import java.util.EventObject;
    import javax.swing.CellEditor;
    import javax.swing.event.CellEditorListener;
    import javax.swing.event.ChangeEvent;
    import javax.swing.event.EventListenerList;
    public class AbstractCellEditor implements CellEditor {
        protected EventListenerList listenerList = new EventListenerList();
        public Object getCellEditorValue() { return null; }
        public boolean isCellEditable(EventObject e) { return true; }
        public boolean shouldSelectCell(EventObject anEvent) { return false; }
        public boolean stopCellEditing() { return true; }
        public void cancelCellEditing() {}
        public void addCellEditorListener(CellEditorListener l) {
         listenerList.add(CellEditorListener.class, l);
        public void removeCellEditorListener(CellEditorListener l) {
         listenerList.remove(CellEditorListener.class, l);
         * Notify all listeners that have registered interest for
         * notification on this event type. 
         * @see EventListenerList
        protected void fireEditingStopped() {
         // Guaranteed to return a non-null array
         Object[] listeners = listenerList.getListenerList();
         // 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==CellEditorListener.class) {
              ((CellEditorListener)listeners[i+1]).editingStopped(new ChangeEvent(this));
    * Notify all listeners that have registered interest for
    * notification on this event type.
    * @see EventListenerList
    protected void fireEditingCanceled() {
         // Guaranteed to return a non-null array
         Object[] listeners = listenerList.getListenerList();
         // 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[i]==CellEditorListener.class) {
              ((CellEditorListener)listeners[i+1]).editingCanceled(new ChangeEvent(this));
    XML Parserimport javax.xml.parsers.SAXParser;
    import javax.xml.parsers.SAXParserFactory;
    import javax.xml.transform.OutputKeys;
    import javax.xml.transform.Transformer;
    import javax.xml.transform.TransformerFactory;
    import javax.xml.transform.dom.DOMResult;
    import javax.xml.transform.sax.SAXSource;
    import org.w3c.dom.Document;
    import org.xml.sax.InputSource;
    import org.xml.sax.XMLReader;
    public class DOMUtil{
    public static Document createDocument(InputSource is) throws Exception{
    SAXParserFactory saxFactory = SAXParserFactory.newInstance();
    SAXParser parser = saxFactory.newSAXParser();
    XMLReader reader = new XMLTrimFilter(parser.getXMLReader());
    TransformerFactory factory = TransformerFactory.newInstance();
    Transformer transformer = factory.newTransformer();
    transformer.setOutputProperty(OutputKeys.INDENT, "no");
    DOMResult result = new DOMResult();
    transformer.transform(new SAXSource(reader, is), result);
    return (Document)result.getNode();
    } The treeimport java.awt.Color;
    import java.awt.Component;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Rectangle;
    import java.awt.event.InputEvent;
    import java.awt.event.MouseEvent;
    import java.util.EventObject;
    import javax.swing.DefaultCellEditor;
    import javax.swing.Icon;
    import javax.swing.JTable;
    import javax.swing.JTextField;
    import javax.swing.JTree;
    import javax.swing.ListSelectionModel;
    import javax.swing.LookAndFeel;
    import javax.swing.UIManager;
    import javax.swing.border.Border;
    import javax.swing.event.ListSelectionEvent;
    import javax.swing.event.ListSelectionListener;
    import javax.swing.table.TableCellRenderer;
    import javax.swing.tree.DefaultTreeCellRenderer;
    import javax.swing.tree.DefaultTreeSelectionModel;
    import javax.swing.tree.TreeCellRenderer;
    import javax.swing.tree.TreeModel;
    import javax.swing.tree.TreePath;
    public class JTreeTable extends JTable {
         /** A subclass of JTree. */
         protected TreeTableCellRenderer tree;
         public JTreeTable(TreeTableModel treeTableModel) {
              super();
              // Creates the tree. It will be used as a renderer and editor.
              tree = new TreeTableCellRenderer(treeTableModel);
              // Installs a tableModel representing the visible rows in the tree.
              super.setModel(new TreeTableModelAdapter(treeTableModel, tree));
              tree.setCellRenderer(new XMLTreeTableCellRenderer());
              // Forces the JTable and JTree to share their row selection models.
              ListToTreeSelectionModelWrapper selectionWrapper = new ListToTreeSelectionModelWrapper();
              tree.setSelectionModel(selectionWrapper);
              setSelectionModel(selectionWrapper.getListSelectionModel());
              // Installs the tree editor renderer and editor.
              setDefaultRenderer(TreeTableModel.class, tree);
              setDefaultEditor(TreeTableModel.class, new TreeTableCellEditor());
              // No grid.
              setShowGrid(false);
              // No intercell spacing
              setIntercellSpacing(new Dimension(0, 0));
              // And update the height of the trees row to match that of
              // the table.
              if (tree.getRowHeight() < 1) {
                   // Metal looks better like this.
                   setRowHeight(20);
         * Overridden to message super and forward the method to the tree. Since the
         * tree is not actually in the component hierarchy it will never receive
         * this unless we forward it in this manner.
         public void updateUI() {
              super.updateUI();
              if (tree != null) {
                   tree.updateUI();
                   // Do this so that the editor is referencing the current renderer
                   // from the tree. The renderer can potentially change each time
                   // laf changes.
                   setDefaultEditor(TreeTableModel.class, new TreeTableCellEditor());
              // Use the tree's default foreground and background colors in the
              // table.
              LookAndFeel.installColorsAndFont(this, "Tree.background",
                        "Tree.foreground", "Tree.font");
         * Workaround for BasicTableUI anomaly. Make sure the UI never tries to
         * resize the editor. The UI currently uses different techniques to paint
         * the renderers and editors; overriding setBounds() below is not the right
         * thing to do for an editor. Returning -1 for the editing row in this case,
         * ensures the editor is never painted.
         public int getEditingRow() {
              return (getColumnClass(editingColumn) == TreeTableModel.class) ? -1
                        : editingRow;
         * Returns the actual row that is editing as <code>getEditingRow</code>
         * will always return -1.
         private int realEditingRow() {
              return editingRow;
         * This is overridden to invoke super's implementation, and then, if the
         * receiver is editing a Tree column, the editor's bounds is reset. The
         * reason we have to do this is because JTable doesn't think the table is
         * being edited, as <code>getEditingRow</code> returns -1, and therefore
         * doesn't automatically resize the editor for us.
         public void sizeColumnsToFit(int resizingColumn) {
              super.sizeColumnsToFit(resizingColumn);
              if (getEditingColumn() != -1
                        && getColumnClass(editingColumn) == TreeTableModel.class) {
                   Rectangle cellRect = getCellRect(realEditingRow(),
                             getEditingColumn(), false);
                   Component component = getEditorComponent();
                   component.setBounds(cellRect);
                   component.validate();
         * Overridden to pass the new rowHeight to the tree.
         public void setRowHeight(int rowHeight) {
              super.setRowHeight(rowHeight);
              if (tree != null && tree.getRowHeight() != rowHeight) {
                   tree.setRowHeight(getRowHeight());
         * Returns the tree that is being shared between the model.
         public JTree getTree() {
              return tree;
         * Overridden to invoke repaint for the particular location if the column
         * contains the tree. This is done as the tree editor does not fill the
         * bounds of the cell, we need the renderer to paint the tree in the
         * background, and then draw the editor over it.
         public boolean editCellAt(int row, int column, EventObject e) {
              boolean retValue = super.editCellAt(row, column, e);
              if (retValue && getColumnClass(column) == TreeTableModel.class) {
                   repaint(getCellRect(row, column, false));
              return retValue;
         * A TreeCellRenderer that displays a JTree.
         public class TreeTableCellRenderer extends JTree implements
                   TableCellRenderer {
              /** Last table/tree row asked to renderer. */
              protected int visibleRow;
              * Border to draw around the tree, if this is non-null, it will be
              * painted.
              protected Border highlightBorder;
              public TreeTableCellRenderer(TreeModel model) {
                   super(model);
              * updateUI is overridden to set the colors of the Tree's renderer to
              * match that of the table.
              public void updateUI() {
                   super.updateUI();
                   // Make the tree's cell renderer use the table's cell selection
                   // colors.
                   TreeCellRenderer tcr = getCellRenderer();
                   if (tcr instanceof DefaultTreeCellRenderer) {
                        DefaultTreeCellRenderer dtcr = ((DefaultTreeCellRenderer) tcr);
                        // For 1.1 uncomment this, 1.2 has a bug that will cause an
                        // exception to be thrown if the border selection color is
                        // null.
                        // dtcr.setBorderSelectionColor(null);
                        dtcr.setTextSelectionColor(UIManager
                                  .getColor("Table.selectionForeground"));
                        dtcr.setBackgroundSelectionColor(UIManager
                                  .getColor("Table.selectionBackground"));
              * Sets the row height of the tree, and forwards the row height to the
              * table.
              public void setRowHeight(int rowHeight) {
                   if (rowHeight > 0) {
                        super.setRowHeight(rowHeight);
                        if (JTreeTable.this != null
                                  && JTreeTable.this.getRowHeight() != rowHeight) {
                             JTreeTable.this.setRowHeight(getRowHeight());
              * This is overridden to set the height to match that of the JTable.
              public void setBounds(int x, int y, int w, int h) {
                   super.setBounds(x, 0, w, JTreeTable.this.getHeight());
              * Sublcassed to translate the graphics such that the last visible row
              * will be drawn at 0,0.
              public void paint(Graphics g) {
                   g.translate(0, -visibleRow * getRowHeight());
                   super.paint(g);
                   // Draw the Table border if we have focus.
                   if (highlightBorder != null) {
                        highlightBorder.paintBorder(this, g, 0, visibleRow
                                  * getRowHeight(), getWidth(), getRowHeight());
              * TreeCellRenderer method. Overridden to update the visible row.
              public Component getTableCellRendererComponent(JTable table,
                        Object value, boolean isSelected, boolean hasFocus, int row,
                        int column) {
                   Color background;
                   Color foreground;
                   if (isSelected) {
                        background = table.getSelectionBackground();
                        foreground = table.getSelectionForeground();
                   } else {
                        background = table.getBackground();
                        foreground = table.getForeground();
                   highlightBorder = null;
                   if (realEditingRow() == row && getEditingColumn() == column) {
                        background = UIManager.getColor("Table.focusCellBackground");
                        foreground = UIManager.getColor("Table.focusCellForeground");
                   } else if (hasFocus) {
                        highlightBorder = UIManager
                                  .getBorder("Table.focusCellHighlightBorder");
                        if (isCellEditable(row, column)) {
                             background = UIManager
                                       .getColor("Table.focusCellBackground");
                             foreground = UIManager
                                       .getColor("Table.focusCellForeground");
                   visibleRow = row;
                   setBackground(background);
                   TreeCellRenderer tcr = getCellRenderer();
                   if (tcr instanceof DefaultTreeCellRenderer) {
                        DefaultTreeCellRenderer dtcr = ((DefaultTreeCellRenderer) tcr);
                        if (isSelected) {
                             dtcr.setTextSelectionColor(foreground);
                             dtcr.setBackgroundSelectionColor(background);
                        } else {
                             dtcr.setTextNonSelectionColor(foreground);
                             dtcr.setBackgroundNonSelectionColor(background);
                   return this;
         * An editor that can be used to edit the tree column. This extends
         * DefaultCellEditor and uses a JTextField (actually, TreeTableTextField) to
         * perform the actual editing.
         * <p>
         * To support editing of the tree column we can not make the tree editable.
         * The reason this doesn't work is that you can not use the same component
         * for editing and renderering. The table may have the need to paint cells,
         * while a cell is being edited. If the same component were used for the
         * rendering and editing the component would be moved around, and the
         * contents would change. When editing, this is undesirable, the contents of
         * the text field must stay the same, including the caret blinking, and
         * selections persisting. For this reason the editing is done via a
         * TableCellEditor.
         * <p>
         * Another interesting thing to be aware of is how tree positions its render
         * and editor. The render/editor is responsible for drawing the icon
         * indicating the type of node (leaf, branch...). The tree is responsible
         * for drawing any other indicators, perhaps an additional +/- sign, or
         * lines connecting the various nodes. So, the renderer is positioned based
         * on depth. On the other hand, table always makes its editor fill the
         * contents of the cell. To get the allusion that the table cell editor is
         * part of the tree, we don't want the table cell editor to fill the cell
         * bounds. We want it to be placed in the same manner as tree places it
         * editor, and have table message the tree to paint any decorations the tree
         * wants. Then, we would only have to worry about the editing part. The
         * approach taken here is to determine where tree would place the editor,
         * and to override the <code>reshape</code> method in the JTextField
         * component to nudge the textfield to the location tree would place it.
         * Since JTreeTable will paint the tree behind the editor everything should
         * just work. So, that is what we are doing here. Determining of the icon
         * position will only work if the TreeCellRenderer is an instance of
         * DefaultTreeCellRenderer. If you need custom TreeCellRenderers, that don't
         * descend from DefaultTreeCellRenderer, and you want to support editing in
         * JTreeTable, you will have to do something similiar.
         public class TreeTableCellEditor extends DefaultCellEditor {
              public TreeTableCellEditor() {
                   super(new TreeTableTextField());
              * Overridden to determine an offset that tree would place the editor
              * at. The offset is determined from the <code>getRowBounds</code>
              * JTree method, and additionally from the icon DefaultTreeCellRenderer
              * will use.
              * <p>
              * The offset is then set on the TreeTableTextField component created in
              * the constructor, and returned.
              public Component getTableCellEditorComponent(JTable table,
                        Object value, boolean isSelected, int r, int c) {
                   Component component = super.getTableCellEditorComponent(table,
                             value, isSelected, r, c);
                   JTree t = getTree();
                   boolean rv = t.isRootVisible();
                   int offsetRow = rv ? r : r - 1;
                   Rectangle bounds = t.getRowBounds(offsetRow);
                   int offset = bounds.x;
                   TreeCellRenderer tcr = t.getCellRenderer();
                   if (tcr instanceof DefaultTreeCellRenderer) {
                        Object node = t.getPathForRow(offsetRow).getLastPathComponent();
                        Icon icon;
                        if (t.getModel().isLeaf(node))
                             icon = ((DefaultTreeCellRenderer) tcr).getLeafIcon();
                        else if (tree.isExpanded(offsetRow))
                             icon = ((DefaultTreeCellRenderer) tcr).getOpenIcon();
                        else
                             icon = ((DefaultTreeCellRenderer) tcr).getClosedIcon();
                        if (icon != null) {
                             offset += ((DefaultTreeCellRenderer) tcr).getIconTextGap()
                                       + icon.getIconWidth();
                   ((TreeTableTextField) getComponent()).offset = offset;
                   return component;
              * This is overridden to forward the event to the tree. This will return
              * true if the click count >= 3, or the event is null.
              public boolean isCellEditable(EventObject e) {
                   if (e instanceof MouseEvent) {
                        MouseEvent me = (MouseEvent) e;
                        // If the modifiers are not 0 (or the left mouse button),
                        // tree may try and toggle the selection, and table
                        // will then try and toggle, resulting in the
                        // selection remaining the same. To avoid this, we
                        // only dispatch when the modifiers are 0 (or the left mouse
                        // button).
                        if (me.getModifiers() == 0
                                  || me.getModifiers() == InputEvent.BUTTON1_MASK) {
                             for (int counter = getColumnCount() - 1; counter >= 0; counter--) {
                                  if (getColumnClass(counter) == TreeTableModel.class) {
                                       MouseEvent newME = new MouseEvent(
                                                 JTreeTable.this.tree, me.getID(), me
                                                           .getWhen(), me.getModifiers(), me
                                                           .getX()
                                                           - getCellRect(0, counter, true).x,
                                                 me.getY(), me.getClickCount(), me
                                                           .isPopupTrigger());
                                       JTreeTable.this.tree.dispatchEvent(newME);
                                       break;
                        if (me.getClickCount() >= 3) {
                             return true;
                        return false;
                   if (e == null) {
                        return true;
                   return false;
         * Component used by TreeTableCellEditor. The only thing this does is to
         * override the <code>reshape</code> method, and to ALWAYS make the x
         * location be <code>offset</code>.
         static class TreeTableTextField extends JTextField {
              public int offset;
              public void reshape(int x, int y, int w, int h) {
                   int newX = Math.max(x, offset);
                   super.reshape(newX, y, w - (newX - x), h);
         * ListToTreeSelectionModelWrapper extends DefaultTreeSelectionModel to
         * listen for changes in the ListSelectionModel it maintains. Once a change
         * in the ListSelectionModel happens, the paths are updated in the
         * DefaultTreeSelectionModel.
         class ListToTreeSelectionModelWrapper extends DefaultTreeSelectionModel {
              /** Set to true when we are updating the ListSelectionModel. */
              protected boolean updatingListSelectionModel;
              public ListToTreeSelectionModelWrapper() {
                   super();
                   getListSelectionModel().addListSelectionListener(
                             createListSelectionListener());
              * Returns the list selection model. ListToTreeSelectionModelWrapper
              * listens for changes to this model and updates the selected paths
              * accordingly.
              ListSelectionModel getListSelectionModel() {
                   return listSelectionModel;
              * This is overridden to set <code>updatingListSelectionModel</code>
              * and message super. This is the only place DefaultTreeSelectionModel
              * alters the ListSelectionModel.
              public void resetRowSelection() {
                   if (!updatingListSelectionModel) {
                        updatingListSelectionModel = true;
                        try {
                             super.resetRowSelection();
                        } finally {
                             updatingListSelectionModel = false;
                   // Notice how we don't message super if
                   // updatingListSelectionModel is true. If
                   // updatingListSelectionModel is true, it implies the
                   // ListSelectionModel has already been updated and the
                   // paths are the only thing that needs to be updated.
              * Creates and returns an instance of ListSelectionHandler.
              protected ListSelectionListener createListSelectionListener() {
                   return new ListSelectionHandler();
              * If <code>updatingListSelectionModel</code> is false, this will
              * reset the selected paths from the selected rows in the list selection
              * model.
              protected void updateSelectedPathsFromSelectedRows() {
                   if (!updatingListSelectionModel) {
                        updatingListSelectionModel = true;
                        try {
                             // This is way expensive, ListSelectionModel needs an
                             // enumerator for iterating.
                             int min = listSelectionModel.getMinSelectionIndex();
                             int max = listSelectionModel.getMaxSelectionIndex();
                             clearSelection();
                             if (min != -1 && max != -1) {
                                  for (int counter = min; counter <= max; counter++) {
                                       if (listSelectionModel.isSelectedIndex(counter)) {
                                            TreePath selPath = tree.getPathForRow(counter);
                                            if (selPath != null) {
                                                 addSelectionPath(selPath);
                        } finally {
                             updatingListSelectionModel = false;
              * Class responsible for calling updateSelectedPathsFromSelectedRows
              * when the selection of the list changse.
              class ListSelectionHandler implements ListSelectionListener {
                   public void valueChanged(ListSelectionEvent e) {
                        updateSelectedPathsFromSelectedRows();
    The resizerimport java.awt.Container;
    import java.awt.Cursor;
    import java.awt.Dimension;
    import java.awt.Point;
    import java.awt.Rectangle;
    import java.awt.event.MouseEvent;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.JViewport;
    import javax.swing.event.MouseInputAdapter;
    import javax.swing.table.TableColumn;
    public class TableColumnResizer extends MouseInputAdapter{
    public static Cursor resizeCursor = Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR);
    private int mouseXOffset;
    private Cursor otherCursor = resizeCursor;
    private JTable table;
    public TableColumnResizer(JTable table){
    this.table = table;
    table.addMouseListener(this);
    table.addMouseMotionListener(this);
    private boolean canResize(TableColumn column){
    return column != null
    && table.getTableHeader().getResizingAllowed()
    && column.getResizable();
    private TableColumn getResizingColumn(Point p){
    return getResizingColumn(p, table.columnAtPoint(p));
    private TableColumn getResizingColumn(Point p, int column){
    if(column == -1){
    return null;
    int row = table.rowAtPoint(p);
    if(row==-1)
    return null;
    Rectangle r = table.getCellRect(row, column, true);
    r.grow( -3, 0);
    if(r.contains(p))
    return null;
    int midPoint = r.x + r.width / 2;
    int columnIndex;
    if(table.getTableHeader().getComponentOrientation().isLeftToRight())
    columnIndex = (p.x < midPoint) ? column - 1 : column;
    else
    columnIndex = (p.x < midPoint) ? column : column - 1;
    if(columnIndex == -1)
    return null;
    return table.getTableHeader().getColumnModel().getColumn(columnIndex);
    public void mousePressed(MouseEvent e){
    table.getTableHeader().setDraggedColumn(null);
    table.getTableHeader().setResizingColumn(null);
    table.getTableHeader().setDraggedDistance(0);
    Point p = e.getPoint();
    // First find which header cell was hit
    int index = table.columnAtPoint(p);
    if(index==-1)
    return;
    // The last 3 pixels + 3 pixels of next column are for resizing
    TableColumn resizingColumn = getResizingColumn(p, index);
    if(!canResize(resizingColumn))
    return;
    table.getTableHeader().setResizingColumn(resizingColumn);
    if(table.getTableHeader().getComponentOrientation().isLeftToRight())
    mouseXOffset = p.x - resizingColumn.getWidth();
    else
    mouseXOffset = p.x + resizingColumn.getWidth();
    private void swapCursor(){
    Cursor tmp = table.getCursor();
    table.setCursor(otherCursor);
    otherCursor = tmp;
    public void mouseMoved(MouseEvent e){
    if(canResize(getResizingColumn(e.getPoint()))
    != (table.getCursor() == resizeCursor)){
    swapCursor();
    public void mouseDragged(MouseEvent e){
    int mouseX = e.getX();
    TableColumn resizingColumn = table.getTableHeader().getResizingColumn();
    boolean headerLeftToRight =
    table.getTableHeader().getComponentOrientation().isLeftToRight();
    if(resizingColumn != null){
    int oldWidth = resizingColumn.getWidth();
    int newWidth;
    if(headerLeftToRight){
    newWidth = mouseX - mouseXOffset;
    } else{
    newWidth = mouseXOffset - mouseX;
    resizingColumn.setWidth(newWidth);
    Container container;
    if((table.getTableHeader().getParent() == null)
    || ((container = table.getTableHeader().getParent().getParent()) == null)
    || !(container instanceof JScrollPane)){
    return;
    if(!container.getComponentOrientation().isLeftToRight()
    && !headerLeftToRight){
    if(table != null){
    JViewport viewport = ((JScrollPane)container).getViewport();
    int viewportWidth = viewport.getWidth();
    int diff = newWidth - oldWidth;
    int newHeaderWidth = table.getWidth() + diff;
    /* Resize a table */
    Dimension tableSize = table.getSize();
    tableSize.width += diff;
    table.setSize(tableSize);
    * If this table is in AUTO_RESIZE_OFF mode and has a horizontal
    * scrollbar, we need to update a view's position.
    if((newHeaderWidth >= viewportWidth)
    && (table.getAutoResizeMode() == JTable.AUTO_RESIZE_OFF)){
    Point p = viewport.getViewPosition();
    p.x =
    Math.max(0, Math.min(newHeaderWidth - viewportWidth, p.x + diff));
    viewport.setViewPosition(p);
    /* Update the original X offset value. */
    mouseXOffset += diff;
    public void mouseReleased(MouseEvent e){
    table.getTableHeader().setResizingColumn(null);
    table.getTableHeader().setDraggedColumn(null);
    The mainimport java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.io.FileInputStream;
    import java.io.InputStream;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import org.xml.sax.InputSource;
    public class TreeTableExample0 {
         public static void main(String[] args) throws Exception {
              new TreeTableExample0();
         public TreeTableExample0() throws Exception {
              JFrame frame = new JFrame("TreeTable");
              InputStream inputStream = new FileInputStream("c:\\totali.xml");
              InputSource inputSource = new InputSource(inputStream);
              MyTreeTable treeTable = new MyTreeTable(new XMLTreeTableModel(DOMUtil
                        .createDocument(inputSource)));
              frame.addWindowListener(new WindowAdapter() {
                   public void windowClosing(WindowEvent we) {
                        System.exit(0);
              frame.getContentPane().add(new JScrollPane(treeTable));
              frame.pack();
              frame.show();
    The modelimport javax.swing.tree.TreeModel;
    public interface TreeTableModel extends TreeModel
    * Returns the number of available columns.
    public int getColumnCount();
    * Returns the name for column number <code>column</code>.
    public String getColumnName(int column);
    * Returns the type for column number <code>column</code>.
    public Class getColumnClass(int column);
    * Returns the value to be displayed for node <code>node</code>,
    * at column number <code>column</code>.
    public Object getValueAt(Object node

  • Exist a Jtree node.id or something like this ?

    I would want to retrieve a node using a unique 'id', for example the absolute index (into the total nodes count)
    Is there something like this ?
    Can I add a particular property to a node ? ( for example this 'id' if it does not exist )
    Another question :
    If I want to implement a search code, this 'id' can be useful, or must I transverse the whole Jtree
    Thanks

    Hello.
    Do the following:
    1. Go to the Apple Menu at the top left of the screen
    2. Select Software Update...
    3. Install any updates that are found.
    If the Amazon issue continues after these updates, then do this:
    1. Open Safari
    2. Erase any web address you have currently showing (for example www.apple.com or www.google.com)
    3. Type in www.amazon.com
    4. That should take you directly to amazon.com
    It should look like this in your Safari::

  • Problem with JTree and memory usage

    I have problem with the JTree when memory usage is over the phisical memory( I have 512MB).
    I use JTree to display very large data about structure organization of big company. It is working fine until memory usage is over the phisical memory - then some of nodes are not visible.
    I hope somebody has an idea about this problem.

    55%, it's still 1.6Gb....there shouldn't be a problem scanning something that it says will take up 300Mb, then actually only takes up 70Mb.
    And not wrong, it obviously isn't releasing the memory when other applications need it because it doesn't, I have to close PS before it will release it. Yes, it probably is supposed to release it, but it isn't.
    Thank you for your answer (even if it did appear to me to be a bit rude/shouty, perhaps something more polite than "Wrong!" next time) but I'm sitting at my computer, and I can see what is using how much memory and when, you can't.

  • Expanding a JTree Node on selection

    Hi,
    I have a need to expand the node on selection in a JTree. I would like all the children to be recursively expanded and selected.
    I believe the code lies somewhere with in JTree's TreeSelectionListener.
    The code I have is as follows
    tree.addTreeSelectionListener(new TreeSelectionListener()
    public void valueChanged(TreeSelectionEvent evt)
    TreePath[] paths = evt.getPaths();
    for (int i=0; i<paths.length; i++)
    if (evt.isAddedPath(i))
    DataNode node = (DataNode)paths.getLastPathComponent();
    ArrayList aList = node.children();
    if( !aList.isEmpty() )
    for(int j = 0; j<aList.size(); j++)
    TreePath tp = paths[i].pathByAddingChild(aList.get(j));
    System.out.println(tp);
    tree.expandPath(tp);
    }//for
    }//public void ValueChanged
    This does not seem to solve the problem..
    Your comments or help is very much appreciated..
    thanks
    S

    it does work for me (i do it in an action). what doesn't work for you?
    thomas
      public RecursiveExpander() {
        menu = new JPopupMenu();
        JMenuItem expand = new JMenuItem("Expand Recursive");
        expand.addActionListener(this);
        menu.add(expand);
      public void mousePressed(MouseEvent e) {
        theTree = (JTree)e.getSource();
        currentPath = theTree.getPathForLocation(e.getX(), e.getY());
        if ((currentPath != null) &&
            !((TreeNode)currentPath.getLastPathComponent()).isLeaf() &&
            (e.getModifiers() == InputEvent.BUTTON3_MASK)) {
          menu.show(theTree, e.getX(), e.getY());
      public void actionPerformed(ActionEvent ae) {
        new Thread(this).start();
      public void run() {
        theTree.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        try { expand(currentPath); }
        catch (OutOfMemoryError oom) {
          System.gc();
          System.err.println("RecursiveExpander: " + oom);
          JOptionPane.showMessageDialog(null, "RecursiveExpander: " + oom, "Error", JOptionPane.ERROR_MESSAGE);
        theTree.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
      private void expand(TreePath path) {
        theTree.expandPath(path);
        TreeNode start = (TreeNode)path.getLastPathComponent();
        for (int i = 0; i < start.getChildCount(); i++) {
          TreeNode node = start.getChildAt(i);
          if (!node.isLeaf()) {
            expand(path.pathByAddingChild(node));
    }

  • Rename a Jtree node directly & Popup Menu

    Pls assist with codes to rename a Jree node directly without using a dialog box or optionpane. I tried
    tree.startEditingAtPath(/* path of selected node*/);
    to go to edit mode and it does not work.
    II. Is it possible to attach different popmenu to the root, separate from the parent and child? Pls assist with code as the popupmenu i use at the moment shows up on the nodes(root, parent, leaf).
    I have benefiited greatly from questions asked and answers proferred at this forum and I use this opportunity to thank everyone greatly as I have migrated to Java based on all the materials sourced on the net.
    [email protected]

    public class AutomatedTreeMouseHandler extends MouseAdapter {
         public void mousePressed(MouseEvent e) {
              JTree tree = (JTree) (e.getSource());
              int x = e.getX();
              int y = e.getY();
              TreePath path = tree.getPathForLocation(x, y);
              if (path != null) {
                   // generate your popup here
    Dennis,
    are you saying that i have to define the popmenu for each category of node in the mouseadapter and att'd these to the tree depending on whether root, leaf or whatever type of node is selected?
    I will try this and revert.
    I can not make anything out of the reference giving with regard to renaming a node in edit mode.
    Pls provide more explanation and sample code, if necessary.
    Thanks a million.

  • How do I use JPanel as a leaf in JTree ?

    Hi All,
    I am a bit of a newbie and I've been trying to change the behavior of my application.
    I have a JTree that I now want to change the rendering of a leaf to be a JPanel. The JPanel will have a couple of JButtons and some text and the user can interact with the JButtons. I was successful in creating the JPanel, adding the buttons and then making my own TreeCellRenderer. Everything displays fine, but the user can not interact with the JButtons, whenever I click on a button in the leaf, the whole leaf is highlighted - I suppose I should not be surprised because this is probably behaving just a cell in a JTree should.
    So I searched the forums and used Google and have found several examples of people using JCheckBox as nodes/leaf(s) in a JTree but none with a JPanel as a leaf. I took one of the check box demos from here ( [http://www.coderanch.com/t/330630/Swing-AWT-SWT-JFace/java/add-swing-component-tree]) and then hacked it a bit but am stuck with the following error :
    Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to javax.swing.JPanel
    which is pointing to the line with JPanel temp2 = (JPanel) temp.getUserObject();
    Does anyone have either some code or suggestions to accomplish a leaf as a JPanel with some buttons ?
    Thanks in advance !
    import javax.swing.*;*
    *import javax.swing.tree.*;
    import java.awt.event.*;*
    *import java.awt.*;
    public class treedemo1 extends JFrame {
        public treedemo1() {
            super("TreeDemo");
            setSize(1500, 1500);
            JPanel p = new JPanel();
            p.setLayout(new BorderLayout());
            customLeafPanel cp1 = new customLeafPanel();
            customLeafPanel cp2 = new customLeafPanel();
            customLeafPanel cp3 = new customLeafPanel();
            DefaultMutableTreeNode root = new DefaultMutableTreeNode("Query Results");
            DefaultMutableTreeNode n1 = new DefaultMutableTreeNode(cp1, false);
            DefaultMutableTreeNode n2 = new DefaultMutableTreeNode(cp2, false);
            DefaultMutableTreeNode n3 = new DefaultMutableTreeNode(cp3, false);
            root.add(n1);
            root.add(n2);
            root.add(n3);
            JTree tree = new JTree(root);
            p.add(tree, BorderLayout.NORTH);
            getContentPane().add(p);
            TestRenderer tr = new TestRenderer();
            tree.setEditable(false);
            tree.setCellRenderer(tr);
        public class customLeafPanel extends JPanel {
            public customLeafPanel() {
                JPanel clpPanel = new JPanel();
                JButton helloJButton = new JButton("Hello");
                this.add(helloJButton);
        public class TestRenderer implements TreeCellRenderer {
            transient protected Icon closedIcon;
            transient protected Icon openIcon;
            public TestRenderer() {
            public Component getTreeCellRendererComponent(JTree tree,
                    Object value,
                    boolean selected,
                    boolean expanded,
                    boolean leaf,
                    int row,
                    boolean hasFocus) {
                DefaultMutableTreeNode temp = (DefaultMutableTreeNode) value;
                JPanel temp2 = (JPanel) temp.getUserObject();
                return temp2;
            public void setClosedIcon(Icon newIcon) {
                closedIcon = newIcon;
            public void setOpenIcon(Icon newIcon) {
                openIcon = newIcon;
        public static void main(String args[]) {
            JFrame frame = new treedemo1();
            frame.addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                    System.exit(0);
            frame.pack();
            frame.setVisible(true);
    }

    Thank you TBM and DB for your replies ! Adding TBM's code does indeed fix the JPanel issue and as TBM indicated this does not actually solve my ultimate problem (Can I give you each 1/2 the Duke points?)
    As a newbie, I am still learning and DB pointed out that "You can however interact with an editor". So after reading the suggested tutorials and looking back at the example code that I hacked. I added the cellEditor back in and it WORKS ! Its funny, I deleted that bits of code from the example, assuming the cellEditor allows you to "edit" (ie change), not interact with it (symantics I guess)
    Thanks again guys for pointing this newbie in the right direction. Frankly I am somewhat surprised that I could finally begin to read and understand what the tutorial and suggestions are telling me ! What is one step up from a newbie ?
    unfortunately I can not post the code because the length of the message is > 5000 :(

  • Problem in Jtree while retrieving values from a hashtable

    Hi
    I am trying to show some values in a Jtree.I am receiving the values in a hashtable.The hashtable contains unique key but duplicate values.i want to show that values of that hashtable in a tree(but unique values)and under each value show all the key of it.can you please tell me how to do that.
    thanks

    If i understand right, you want to do something like this:
                   Hashtable values = yourhashtable;        
              DefaultMutableTreeNode root = new DefaultMutableTreeNode("Values");
              HashMap<Object, DefaultMutableTreeNode> nodes = new HashMap<Object, DefaultMutableTreeNode>();
              Iterator ii = values.keySet().iterator();
              while (ii.hasNext()) {
                   Object key = ii.next();
                   Object value = values.get(key);
                   if (nodes.containsKey(value)) {
                        DefaultMutableTreeNode node = nodes.get(value);
                        DefaultMutableTreeNode child = new DefaultMutableTreeNode(key);
                        node.add(child);
                   } else {
                        DefaultMutableTreeNode node = new DefaultMutableTreeNode(value);
                        DefaultMutableTreeNode child = new DefaultMutableTreeNode(key);
                        node.add(child);
                        nodes.put(value, node);
                        root.add(node);
              JTree tree = new JTree(root);Hope this helps,
    Alex.

Maybe you are looking for