JTree custom implementation

Hi All,
I have application, which eats all the memory, when I load big structure in JTree.
So I have modified following function
DefaultTreeMutableNode {
public void insert(MutableTreeNode newChild, int childIndex) {
          children = new Vector();
As follow:
DefaultTreeMutableNode {
public void insert(MutableTreeNode newChild, int childIndex) {
          children = new ArrayList(1);
As my jTree usually has single nodes. And Default constructor of Vector() creates array of 10 child nodes, for each node.
But still it uses the same memory ???
Is there any way to reduce memory usage by JTree nodes, so it can handle big strucutre.
Is there any custom implemenation is avaliable.
Thank you for your time.
Avin Patel

I guess ur application is a perfect candidate for a MVC implementation. In the tree there are 2 ways to do that. u can either write ur own TreeModel or u can write ur ur own TreeNode. I can help u write either of the two.
I can give u working examples from my application in each of them. U can also make the creation of the child nodes dyanamic and on a "on-demand-basis", by creating them only on the expansion of the parent nodes, as mentioned above.
The first way to do that is to override the implementation of the DefaultTreeModel class:
Plz find below an implementaion of the same:
public class GrpModuleTreeModel extends DefaultTreeModel
     TerminationPointsModel mModel = null;
     TreePanel mTreePanel;
     GrpModuleTreeModel(TerminationPointsModel model,TreePanel treePanel)
          super(null);
          mModel = model;
          mTreePanel=treePanel;
     public int getIndexOfChild(Object parent, Object child)
          if (parent.equals(mTreePanel.mParent.getParentFrame().getNEName()))
               ArrayList rackList = new ArrayList(mModel.getRacks());
               return rackList.indexOf(child);
          if (parent instanceof Rack)
//               return mModel.getSubracks(parent).size();
               ArrayList subrackList = new ArrayList(((Rack)parent).getSubracks());
               return subrackList.indexOf(child);
          if (parent instanceof Subrack)
//               return mModel.getModules(parent).size();
               ArrayList moduleList = new ArrayList(((Subrack)parent).getModules());
               return moduleList.indexOf(child);
          if (parent instanceof Module)
//               return this.mModel.getTerminationPoints(parent).size();
               ArrayList tpList = new ArrayList(((Module)parent).getTerminationPoints());
               return tpList.indexOf(child);
          if (parent instanceof TerminationPointA)
//               return this.mModel.getTerminationPoints(parent).size();
               ArrayList tpList = new ArrayList(((TerminationPointA)parent).getTerminationPointList());
               return tpList.indexOf(child);
          return -1;
     public boolean isLeaf(Object node)
          if (node instanceof TerminationPointA )
               if (node instanceof NonConfigurableCrossConnection ) return true;
               return (((TerminationPointA)node).getTerminationPointList()==null)? true: false;
//               java.util.ArrayList list=((TerminationPointA)node).getTerminationPointList();
//               System.out.println("Type====== "+((TerminationPointA)node).getTerminationPointType()+","+list);
//               if (list!=null)
//                    System.out.println("Number of nodes ========= "+list.size());
//                    for (int i = 0; i < list.size(); i++)
//                         System.out.println(list.get(i).getClass().getName());
//               return true;
          if (node instanceof Rack)
               return (((Rack)node).getSubracks()==null)? true: false;
          if (node instanceof Subrack)
               return (((Subrack)node).getModules()==null)? true: false;
          if (node instanceof Module)
               return (((Module)node).getTerminationPoints()==null)? true: false;
          return false;
     public Object getChild(Object parent, int index)
          if (parent.equals(mTreePanel.mParent.getParentFrame().getNEName()))
               ArrayList rackList = new ArrayList(mModel.getRacks());
               return (rackList!=null)? rackList.get(index):null;
          if (parent instanceof Rack)
//               return mModel.getSubracks(parent).size();
               ArrayList subrackList = new ArrayList(((Rack)parent).getSubracks());
               return (subrackList!=null? subrackList.get(index):null);
          if (parent instanceof Subrack)
//               return mModel.getModules(parent).size();
               ArrayList moduleList = new ArrayList(((Subrack)parent).getModules());
               return moduleList!=null? moduleList.get(index):null;
          if (parent instanceof Module)
//               return this.mModel.getTerminationPoints(parent).size();
               ArrayList tpList = new ArrayList(((Module)parent).getTerminationPoints());
               return tpList!=null? tpList.get(index):null;
          if (parent instanceof TerminationPointA)
//               return this.mModel.getTerminationPoints(parent).size();
               ArrayList tpList = new ArrayList(((TerminationPointA)parent).getTerminationPointList());
               return tpList.get(index);
          return null;
     public int getChildCount(Object parent)
          if (parent ==null)
               return -1;
          if (parent.equals(mTreePanel.mParent.getParentFrame().getNEName()))
               return mModel.getRacks()!=null ? mModel.getRacks().size() : -1;
          if (parent instanceof Rack)
//               return mModel.getSubracks(parent).size();
               return ((Rack)parent).getSubracks()!=null ? ((Rack)parent).getSubracks().size() : -1;
          if (parent instanceof Subrack)
//               return mModel.getModules(parent).size();
               return ((Subrack)parent).getModules()!= null? ((Subrack)parent).getModules().size() : -1;
          if (parent instanceof Module)
//               return this.mModel.getTerminationPoints(parent).size();
               return ((Module)parent).getTerminationPoints() != null ? ((Module)parent).getTerminationPoints().size(): -1;
          if (parent instanceof TerminationPointA)
//               return this.mModel.getTerminationPoints(parent).size();
               return ((TerminationPointA)parent).getTerminationPointList()!= null ? ((TerminationPointA)parent).getTerminationPointList().size(): -1;
          return -1;
     public Object getRoot()
          return mTreePanel.mParent.getParentFrame().getNEName();
IF this does'nt suffice then I can tell u another way by which u can create ur own TreeNode.
BR
Mohit

Similar Messages

  • Financial Accountig missing in SAP Customizing Implementation Guide

    Hi
    After upgrading SAP ERP 2004 to SP-Stack 17, the entry "Financial Accounting" is missing in SAP Customizing Implementation Guide (Transaction SPRO).
    Any ideas?
    Thanks
    Andreas

    The problem was solved. See Note 922552.

  • A Customer Implementation cannot be migrated into a SAP implementation

    Hi all,
    I am writing badi implementation to add a field in the customer master transaction screen(xd03). when i try to activate the badi implementation, it is giving a messge in the a information window saying that "<b> A Customer Implementation cannot be migrated into a SAP implementation</b>" Can anybody suggest what exactly is that? How to resolve it? and the BADI implementation is not activated.
    Please suggest me.
    Thanks inadvance.kp

    Hi,
    Seema that your procedure is not suitabe to SAP. Make sure you have done the following :
    Go to Transaction SPRO à Logistics – General à Business Partner à Customers à Control à Adoption of Customer’s own Master Data fields à Prepare Modification à Free enhancement of Customer Master Record
    Thanks

  • Customer Implementation

    Hi all,
    Is anyone doing a customer implementation of CE?
    Is a stable full release available with Portal(the preview version has an application server only). If it is not available when SAP will be releasing it?(If anyone can provide a roadmap it will be really helpful)
    Are features like netweaver voice available with the current version?
    No guesses please....
    Rohit

    Hi
    Today, integration complexity has no boundaries. Many applications and components in customer system landscapes are directly connected point-to-point, with all integration capabilities hardwired into the application components and individual mapping programs.
    A common complex IT landscape at a customer site is sort of ”spider web” and is the representative of today’s application integration challenge. What you see is a wildly grown integration landscape with different application systems and multiple individual connections between different interfaces. Connecting these applications does not only lead to a high complexity in managing and maintaining – there is also a lot of cost associated with it.
    These systems have been integrated over time using whatever integration technology or middleware was available. The integration knowledge is hidden within the different applications or within the used middleware tools and the interface descriptions.

  • Problem with JTree custom renderer when editing

    I have a JTree which uses a custom renderer to display my own icons for different types of nodes. The problem I am having is when I setEditable to true and then attept to edit a node the icon switches back to the default icon, as soon as I am done editing it goes back.
    What I am doing wrong?

    Here is my rendererer
    public class DeviceTreeRenderer extends DefaultTreeCellRenderer implements GuiConstants {
       public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
          JLabel returnValue = (JLabel)super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
          if (value != null) {
             returnValue.setToolTipText(value.toString());
          if (value instanceof Device) {
             returnValue.setIcon(TREE_DEVICE);
             if (!((Device)value).isAlive()) {
                returnValue.setEnabled(false);
          else if (value instanceof GuiPanelGroup) {
             if (expanded) {
                returnValue.setIcon(TREE_PANEL_GROUP_OPEN);
             else {
                returnValue.setIcon(TREE_PANEL_GROUP_CLOSED);
          else if (value instanceof GuiPanel && ((GuiPanel)value).isDirty()) {
             returnValue.setIcon(TREE_PANEL_DIRTY);
          return returnValue;
    }Here is my editor:
    public class WwpJTreeCellEditor extends DefaultTreeCellEditor implements GuiConstants {
          private WwpJTree tree;
           * Creates a new WwpJTreeCellEditor.
           * @param tree The WwpJTree to associate with this editor.
          public WwpJTreeCellEditor(WwpJTree tree) {
             super(tree, (DefaultTreeCellRenderer)tree.getCellRenderer());
             this.tree = tree;
           * Overrides the default isCellEditable so that we check the isEditable() method
           * of the WwpJTreeNodes.
           * @param e An EventObject.
          public boolean isCellEditable(EventObject e) {
             boolean returnValue = super.isCellEditable(e);
             if (returnValue) {
                WwpJTreeNode node = this.tree.getSelectedNode();
                if (node == null || !node.isEditable() || node.isDragging()) {
                   returnValue = false;
             return returnValue;
       }In my JTree I make these calls:
    super.setCellRenderer(new DeviceTreeRenderer());
    super.setCellEditor(new WwpJTreeCellEditor(this));
    super.setEditable(true);

  • 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

  • JTREE: Custom TreeModel does not update non-root nodes

    I have a JTree that uses a custom TreeModel that wraps over (delegates to) a data class X which keeps track of all its children. The class X maintains its own data structure internally (references to other data objects). It also implements 'equals' and 'hashcode' methods. When the data changes in X, it invokes fireTreeStructureChanged on the TreeModel. (There is a TreeModelListener registered with the TreeModel). This works very well for the root node but not for the other non-root nodes. The JTree correctly calls 'equals' and I can see that equals returns 'false' but for non-root nodes the JTree does not refresh though I can see the underlying data structure has changed.
    I am wondering if I may not have fully & correctly implemented fireTreeStructureChanged as it doesn't seem to do much. Or I may be looking at the wrong place. Any pointers would be appreciated.
    BTW, this question is very similar to one asked years earlier http://forums.sun.com/thread.jspa?threadID=153854 but it didn't help me :(
    Thanks.
    ps: working with jdk1.6.0_06 on WinXP.

    I have a same problem. I got an error "Cannot Update Libray".

  • Making JTree custom renderer panel scalable

    Hi, everyone. I have made custom TreeCellRenderer which extends JPanel. Panel's background is in different color than JTree's backgound. I need to get my panel rendering the nodes to fill the whole space JTree has in it's parent panel horizontally. For now I have put static width to nodes and it looks fine, but it's not scalable. If I don't put any sizes the panel takes only the size it needs in cell and the outfit is crappy because of panel's different bgcolor. Is there any easy way to make rendering panel use the width which JTree has in it's container. I have implemented getPreferredSize() method in custom TreeCellRenderer and now it returns the static width and height of the rendering panel. Do I have to get JTrees container panel's width every time and pass it to renderer and get size somehow from there or is there some easier way.
    -e

    Yes, there is a reason. Different levels of nodes contain different components. Example main level nodes have print and save buttons on the most right of the panel. Only leafs have same bgcolor as the tree has and those are already now scalable, because size is not set for them.

  • JTree Custom TreeCellRenderer problem on Mac OS + Firefox

    Hi,
    I have a JApplet containing a JTree component with custom renderer that implements TreeCellRenderer to display CheckBox along the tree nodes.
    Everything works fine on Window and Linux OS (firefox browser)
    Problem is with :
    Firefox + Mac: applet fails to load because getTreeCellRendererComponent() does not seem to get invoked.
    Appreciate you time and thoughts on the problem.
    Edited by: rg18mar on Nov 27, 2007 10:31 PM

    Our only other environment we could set up was on Mac OS 10.7.5, and we could not reproduce the issue.  Based on that it would appear to be something new with Mac OS 10.8.

  • Jtree custom selection

    I use the jTree. When an element is selected - i dont like how it looks.
    Check the screenshot : there are two selected areas - a standart one (top) and a custom one(bottom), dont pay attention to the gradient.
    The designer made an improved variant. As you can see, the selection exceeds the jTree and goes over the JPanel, which comprises the jTree.
    How can I make it like this in my app?
    P.S.
    I have an idea to make a half-transparent JPanel and place it over the tree... but I am not sure about the TRUE-ness of this solution :)

    I use the jTree. When an element is selected - i dont like how it looks.
    Check the screenshot : there are two selected areas - a standart one (top) and a custom one(bottom), dont pay attention to the gradient.
    The designer made an improved variant. As you can see, the selection exceeds the jTree and goes over the JPanel, which comprises the jTree.
    How can I make it like this in my app?
    P.S.
    I have an idea to make a half-transparent JPanel and place it over the tree... but I am not sure about the TRUE-ness of this solution :)

  • JTree custom renderer - JScrollPane

    Hi,
    I am building a JTree and need a custom renderer that will allow me to display the contents of certain leaf nodes in a JEditorPane that is contained in a scrollpane as the leaf may contain a varying amount of text.
    I have managed to get a renderer displaying the text as expected however the scrollbars do not work as I hoped - I cannot scroll down the editorpane.
    Has anyone got an example of a renderer that uses a scrollpane, any help/suggestions would be gratefully received.
    Thanks

    Return the size of your editor pane in customized cell renderer's getPreferredSize() method and set JTree rowHeight to zero. When row height is 0, it use renderer's getPreferredSize() to get size of the cell, I think. I have made custom cellrenderer which extends Jpanel and in getCellRendererComponent I add there another panel which contains buttons etc. I have used super.getPreferredSize() in my renderer's getPreferredSize() method.

  • JTree custom icon help

    Hi, i am trying to get custom icon for specific nodes of a tree. In my customTreeCellrenderer that extends the default predecessor, i have this function. The problem is that, the icons are not set to the node i want but the node after that node. Anyone got any suggestions as to what i am doing wrong ?
    Thanks, Dave
         public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
              ImageIcon error = new ImageIcon("illegal.gif");
              super.getTreeCellRendererComponent(tree, value, sel,expanded, leaf, row,hasFocus);
              DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
              GroupNodeObject obj = (GroupNodeObject) node.getUserObject();
              if(node.getUserObject() instanceof GroupNodeObject){
                   if(obj.isIllegal()){
                        this.setLeafIcon(error);
                        this.setClosedIcon(error);
                        this.setOpenIcon(error);
                   }else{
                        this.setLeafIcon(getDefaultLeafIcon());
                        this.setClosedIcon(getDefaultClosedIcon());
                        this.setOpenIcon(getDefaultOpenIcon());
              return this;
         }

    may be the next node is instance of GroupNode!!
    just incase, check the code if the error is assigning the nodes!
    This code looks ok.

  • JTree custom cell renderer question

    When using a custom cell renderer is their anyway to tell the offset of the current node?
    For example if you have a tree with the parent node "Parent" that has a few children nodes it will look something like this:
    Parent
    |----Child 1
    |----Child 2
    |----Child 3
    So the parent would have an offset of zero. I want to know how to get the childrens offset? If this is possible?
    What I am trying to accomplish:
    I have a JTree as a scrollpane rowHeader. While the main body of the scrollpane is a JTable. I need the tree's nodes to fill the entire width so that it looks like part of the table. I figure the row header width - current node offset should be the width that I will need each node to be. Any help is welcome. Thanks.

    the renderer tells you the row, the tree can get you a treepath for a row
    TreePath getPathForRow(int row)
    That can tell you the depth of the node.

  • JTree custom DefaultTreeCellRenderer with custom DefaultMutableTreeNode

    Is there a way to create my own version of DefaultTreeCellRenderer that does not use DefaultMutableTreeNode? I tried copying an example of a custom DefaultTreeCellRenderer but I can’t cast the "value" in getTreeCellRendererComponent() to my own version of DefaultMutableTreeNode.
    From the looks of the documentation below shouldn't I be able to do that?
    Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus)

    oops,
    I found out why. I created my custom DefaultTreeCellRenderer before I populated the root node with my DefaultMutableTreeNode. So I guess, java went with the default. When I created my custom DefaultTreeCellRenderer after I populated the root node, everything worked.

  • JTree customized model

    Hi all, I have a hierarchy of tree nodes (MutableTreeNode), and I want to implement my tree model to not display all nodes passed to him, I want to display nodes wich satisfy special criteria, depending on some attributes in tree node it will be displayed or not.
    How to achieve that?
    Thanks
    Ahmad Elsafty

    I am doing basically the same thing in a custom TreeModel. I simply have most of the logic in the getChildren(Object parent) method, so I fetch all the children and then filter out the ones I don't want and return the rest.

Maybe you are looking for

  • How to insert data into table control

    hi experts,,        i have inserted data into data base table through table control . now i want to insert data into table control through database table.   how to delete data from table control for selected row

  • Unzip error in step 4 of 5. Installation failing

    Hi, I am trying to install EBS R12.1.1 on my Windows XP SP3 machine. I use cygwin instead of MKS toolkit (for obvious reasons). The installation proceeds fine. It installs the DB without any problems and the whole process goes fine until step 4. Here

  • Webadmin vs NetWeaver  Administrator

    Hi all, hopefully someone can help me clear up something. We have a CRM 4.0 system with a WebAS Java 6.40 SP9. This system has a J2EE Example: Web Administrator application (technical name: sap.com/webadmin). This is marked as an example tool, but se

  • Lens Profile Downloader ?

    I have downloaded  subject and companion programme AIR. Selected my 24-70 ZA lens and downloader says installed. Yet when I load up LR (3.5)  the new lens does not show in the Sony le s profiles just the same old 4 lens that LR comes with. What is go

  • How can I view the files I have in an USB in an IPad mini

    I have an IPad mini and I would like to view some files I have in an USB memory in my apple device, I can connect the USB to the IPad mini but I cannot see the files. Thank you!