JTreeTable rendering

I have a problem with rendering some labels in a first column of table (Tree's leafs) in some cases. They just doesn't rendered at all. It especially appears when using multiple embranchment.
Maybe someone faced something similar and can give any advice how to avoid this problem?
Or maybe any good resources about TreeTables for Java other than that on Sun's web site. Maybe others more robust implementations of it somewhere.
Thanks in advance.

You can set the background of the JScrollPane's viewport to white:
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.getViewport().setBackground(Color.white);

Similar Messages

  • JTreeTable rendering problems

    Hi all!
    I have used some clesses to create a JTable containing a JTree, basing on the example in the sun's site. The costructor is:
    JFrame frame = new JFrame("TITLE");
    JTreeTable table = createTable(); //Creates the treetable
    JScrollPane scrollPane = new JScrollPane(table); //it puts the newly created table in a scrollPane
    frame.getContentPane().add(scrollPane,BorderLayout.CENTER);
    frame.pack();
    frame.show();
    I have the following problems:
    1. If I have not many nodes in the tree, I have a bad renderer effect: the table doesn't fit the whole window but just the upper part of that, at the bottom it's all gray (the JFrame color, I think).Even if I set the JFrame background color to white, I still have that problem.
    2. If I don't add the table to the scrollbar, I can't see the headers, but I don't have the problem of the gray panel.
    Does anyone know how I can work out this? Has anybody examples of JTreeTables that don't have this rendering problem (with the table fitting the whole window even though they don't have many nodes)?
    Feedbacks are welcome, this is really showstopper for me...
    Thanks a lot!

    Hi there.
    Try setting the viewport color of your scrollpane. I don't have my API's on hand but you go something like myScrollPane.getViewport().setBackgroundColor(Color.white);
    How does that go for you?
    Cheers,
    Rachel

  • Help with JTreeTable custom cell renderer!

    Hi.
    I've followed diligently the complete TreeTable2 example found on the Sun site. http://java.sun.com/products/jfc/tsc/articles/treetable2/
    What I'm trying to do is to add alternate-row shading on the Column(0) of the JTreeTable where the Column class is "TreeTableModel".
    so, from the example, I've added the following setCellRenderer declaration to TreeTableExample2.java:
         protected JTreeTable createTreeTable() {
              JTreeTable       treeTable = new JTreeTable(model);
              treeTable.getColumnModel().getColumn(1).setCellRenderer
              (new IndicatorRenderer());
              treeTable.getColumnModel().getColumn(0).setCellRenderer
              (new MyTableCellRenderer());Then, I subclass DefaultTableCellRenderer as shown below, in a new class called "MyTableCellRenderer"
    import java.awt.Color;
    import java.awt.Component;
    import javax.swing.JTable;
    import javax.swing.table.DefaultTableCellRenderer;
    import javax.swing.table.TableCellRenderer;
    public class MyTableCellRenderer extends DefaultTableCellRenderer implements TableCellRenderer
         private static final long serialVersionUID = 1L;
         public MyTableCellRenderer() {
         public Component getTableCellRendererComponent(JTable jtable, Object obj, boolean isSelected, boolean hasFocus, int i, int j)
              if (i % 2 == 0 && !isSelected) {
                   this.setBackground(new Color(214,226,255));
                   this.setForeground(Color.BLACK);
              } else if (isSelected)
                   this.setBackground(new Color(204, 204, 255));
              else {
                   this.setBackground(Color.white);
              //if (obj != null)
              this.setValue(obj.toString());
              System.out.println("obj: " + obj.toString());
              System.out.println("obj type: " + obj.getClass().getName());
              return ((Component) (this));
    }I've been pulling out whatever few hairs I have left in my sparse scalp to get this working, but it's looking grim thus far.
    Here are links to screenshots of my progress, or lack thereof:
    Original Working TreeTable II
    http://www.pharmalytix.com/original_treetable.jpg
    My Not-working Tree Table II w/ Custom Cell Renderer
    http://www.pharmalytix.com/customtablecellrenderer_treetable.jpg
    thanks again - !!

    phew! finally got this sucker working. I had to retrieve the default rendererer of my TreeTable's TreeTableModel class column, which is the JTree and then, in its component-form, start mucking about with its stylings. The real black-hole of progress was caused by my brain imploding from not being able to understand that a "Component" was what represented the "thing" whose behaviour I wanted to alter, be it a Jtree node or Jtable cell.
              treeTable.getColumnModel().getColumn(0).setCellRenderer(new TableCellRenderer() {
                   public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
                        Component comp = treeTable.getDefaultRenderer(TreeTableModel.class).getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
                        if (row % 2 == 0 && !isSelected) {
                             comp.setBackground(new Color(214,226,255));
                             comp.setForeground(Color.BLACK);
                        } else
                             if (isSelected)
                                  comp.setBackground(new Color(204, 204, 255));
                             else {
                                  comp.setBackground(Color.white);
                        return comp;
              });In all of its ravishing glory:
    http://www.pharmalytix.com/alternateshading_treetable.jpg
    Edited by: DataHog on Nov 6, 2007 10:21 AM

  • 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

  • Using JTreeTable as a Bean

    Hi,
    I've been looking at the JTreeTable class available at:
    http://java.sun.com/products/jfc/tsc/articles/treetable1/
    This is not a standard Swing component but I'd like to use it as a Bean so that I can load it into my NetBeans IDE. Problem is there does not appear to be a means to set the model (for tree and table) other than using the constructor that takes a TreeTableModel parameter.
    Has this been done before? Any help is appreciated.
    Thanks,
    Derek.

    Mabe you also should rewrite the other constructor:
    public JTreeTable(TreeTableModel treeTableModel) {
         super();
            setTreeTableModel(treeTableModel);
            // Installs the tree editor.
            setDefaultEditor(TreeTableModel.class, new TreeTableCellEditor());
         // No grid.
         setShowGrid(false);
         // No intercell spacing
         setIntercellSpacing(new Dimension(0, 0));     
    public void setTreeTableModel(TreeTableModel treeTableModel){
         // 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));
         // Forces the JTable and JTree to share their row selection models.
         ListToTreeSelectionModelWrapper selectionWrapper = new
                                 ListToTreeSelectionModelWrapper();
         tree.setSelectionModel(selectionWrapper);
         setSelectionModel(selectionWrapper.getListSelectionModel());
         // Installs the tree renderer
         setDefaultRenderer(TreeTableModel.class, tree);
         // 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 TreeTableModel getTreeTableModel(){
          return getModel();
        }Something like this. Didn't test it!
    -Puce

  • Cell alignment in JTreeTable

    hi,
    how can i set alignment of a cell in a JTreeTable?

    i have the following renderer :
    public class TreeTableCellRenderer extends JTree implements TableCellRenderer,SwingConstants
    protected int visibleRow;
    public TreeTableCellRenderer(TreeModel model) {
    super(model);
    public void setBounds(int x, int y, int w, int h) {
    super.setBounds(x, 0, w, JTreeTable.this.getHeight());
    public void paint(Graphics g) {
    g.translate(0, -visibleRow * getRowHeight());
    super.paint(g);
    public Component getTableCellRendererComponent(JTable table,
    Object value,
    boolean isSelected,
    boolean hasFocus,
    int row, int column) {
    if(isSelected)
    setBackground(table.getSelectionBackground());
    else
    setBackground(table.getBackground());
    visibleRow = row;
    return this;

  • Problem when printing JTreeTable

    Hi,
    I've datas wich i display in a JTable or in a JTreeTable (see http://java.sun.com/products/jfc/tsc/articles/treetable1/ ).
    Now, i'd like to print the JTable or the JTreeTable, i use the code i've found here : http://developer.java.sun.com/developer/onlineTraining/Programming/JDCBook/advprint.html .
    There was a bug ( see http://forum.java.sun.com/thread.jsp?forum=57&thread=263303 ).
    The JTable prints itself very fine but i've two problems with the JTreeTable :
    1) I've always some last rows on a page and on the next page, even if i include the table.getRowMargin() or not.
    2) Almost all the node are printed with "...", for instance : TRES -> TR... although they are well displayed on screen.
    It doesn't depend on the width of the column and i can't know how Swing decide or not to display the "..." (for instance, i've "C..." and "CR..." but they are at the same x-location with the same icons, the same font and the same font's size; just not the same number of caracters)
    I don't post any code because it's long, it's just a mix between the links.
    Any help would be great before i kill hundreds of tree.
    Thanks in adavance.
    Fade.

    Hi Fade,
    I am having the same problem in printing a JTreeTable. The nodes of the JTree are getting clipped and are followed by ellipsis(...). A similar problem occurs for the other table columns, if the column separators(borders) are closely aligned with the text. It seems that the space required for rendering the components within the table, is more while printing. The problem is more prominent in case of the tree nodes. In case you have found a solution for the same, it would be nice if u could help me with it. Or if there's any one out there who could be of help, pls. reply.
    Thanx.

  • Custom Renderers in JTreeTable (or extending JTable)?

    I am wondering about what the best approach is to display a table in a Swing component. My table will by default have all rows collapsed (occupying a single line), but someone may click on a row to expand it (so it occupies multiple lines and displays more information). Nothing in the table should be editable.
    Example:
    (collapsed) 1. data     data     data
    (expanded) 2. data     data     data
    ...more data that wouldn't fit on on one line...
    ... still more data (additional data doesn't have same column format as collapsed rows)...
    (collapsed) 3. data     data     dataSo the additional data displayed when a row is expanded aren't conceptually `children' of the data in the collapsed display. I've looked at JTreeTable, but I'm not sure it's right for this purpose, and it seems complicated.
    For one thing, I need some of my columns to have custom renderers--for example, renderers that display a button with text or an image instead of just a label. However, it looks like the JTreeTable approach forces you to declare the JTree (extension) as the renderer of everything in a row, so would that prevent me from specifying custom renderers for other columns, or am I misunderstanding?
    Another feature I need is to be able to filter out entire rows from the view (so they don't show up at all). I will also want to add custom sort buttons that can apply four different sorts to each column.
    Would I be better off using a JTreeTable for this or somehow using custom renderers or otherwise extending an ordinary JTable to make the column larger and display additional information when the user clicks the expand icon?
    Also, how do I specify a different renderer for header rows than for other rows?
    Message was edited by:
    The.Joy.of.Java

    Check how editingStopped is being done. For a ComboBox there is no common operation that one can assume means that the user is done with the editing component. By default JTable leaves it active until the mouse clicks somewhere outside it, then does, essentially, fireEditingStopped() to give the cell back to the renderer. Then a second mouse click is required to start a new cell editor.
    If you're using ComboBox as a custom editor, you have to decide what event you want to be final and call fireEditingStopped() yourself. For instance, in your TableCellEditor:
        @Override
        public Component getTableCellEditorComponent(final JTable table,
                                                     final Object value,
                                                     final boolean isSelected,
                                                     final int row,
                                                     final int column) {
    ...             if( editor.supportsCustomEditor() )  {
                        JComboBox c = (JComboBox)editor.getCustomEditor();
                        c.removeActionListener( this );
                        c.addActionListener( this );
                        return c;
        @Override
        public void actionPerformed ( final ActionEvent ev ) {
            else if( "comboBoxChanged".equals( ev.getActionCommand() ) )  {
                fireEditingStopped();
        }The actionEvent is fired when just about anything happens in the ComboBox, including selection of the currently selected item. But unless you have a more specific requirement, it should be good enough.

  • Multiple DnD in JTreeTable

    Hi Folks--
    two weeks ago I started to implement Drag and Drop for my wonderful TreeTableComponent, that is based on a JTreeTable described in an article by sun. It didn't took me long to figure that dnd is not the easiest thing to do for a JTreeTable. So I browsed this forum and found many other people who have or had the same problem. Since the given answers didn't help me so much, I thought it would be good to publish my implementation here:
    After two weeks I managed to implement dnd in the right way (as I belive). Here's my solution.
    1. disable internal dnd function by setDragEnabled(false)
    2. set your own transfer handler that manages dnd for you (derive from TransferHander or simply create an instance of TransferHandler)
    3. add a mouse listener and a mouse motion listener to your treeTable to tell the transfer handler to start the drag
    4. revert order of mouse listener that you mouse listener is called first -> this is importent to keep selection on all previously selected nodes (prevents internal mouse handler of tree changing selection to the node you just clicked onto)
    5. set selection mode of table and tree to make multiple selection possible to the user
    add this where you init the table:
    ('table' is instance of a JTreeTable derivative)
            //disable internal dnd functionality, because we need our own implementation
            table.setDragEnabled(false); 
           //attach transfer handler
            table.setTransferHandler(createTransferHandler());
            //since we have a transfer handler, we just need to attach mouse listeners
            //to initiate the drag inside of the transfer handler
            DnDMouseAdapter dndMouseAdapter = new DnDMouseAdapter();
            table.addMouseListener(dndMouseAdapter);
            table.addMouseMotionListener(new DnDMouseMotionAdapter());
            //revert MouseListeners order so that our MouseListener is called first
            //this is important to give drag n drop first priority and prevent the
            //internal mouse handler of tableUI changing the selection.
            MouseListener[] mls = table.getMouseListeners();
            for (int i = 0; i < mls.length; i++) {
                if (mls[i] != dndMouseAdapter) {
                    table.removeMouseListener(mls);
    table.addMouseListener(mls[i]);
    //set multiple selection
    table.getSelectionModel().setSelectionMode(getSelectionMode());
    //set selection mode for tree
    final JTree tree = getTreeTable().getTree();
    tree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
    The idea for the mouse listeners I got from sun's swing tutorial. So here's the code for dndMouseAdapter and dndMouseMotionAdapter:
      class DnDMouseAdapter extends MouseAdapter {
            public void mousePressed(MouseEvent e) {
                firstMouseEvent = e;
                e.consume();
            public void mouseReleased(MouseEvent e) {
                firstMouseEvent = null;
        class DnDMouseMotionAdapter extends MouseMotionAdapter {
            //define diplacement of five pixel for as drag
            private static final int PIXEL_DISPLACEMENT = 5;
            public void mouseDragged(MouseEvent e) {
                if (firstMouseEvent != null) {
                    e.consume();
                    //if the user holds down the control key -> COPY, otherwise MOVE
                    int ctrlMask = InputEvent.CTRL_DOWN_MASK;
                    int action = ((e.getModifiersEx() & ctrlMask) == ctrlMask) ? TransferHandler.COPY : TransferHandler.MOVE;
                    int dx = Math.abs(e.getX() - firstMouseEvent.getX());
                    int dy = Math.abs(e.getY() - firstMouseEvent.getY());
                    //define a displacement of at least some pixel as a drag
                    if (dx > DnDMouseMotionAdapter.PIXEL_DISPLACEMENT || dy > DnDMouseMotionAdapter.PIXEL_DISPLACEMENT) {
                        //starting to drag...
                        JComponent c = (JComponent) e.getSource();
                        TransferHandler handler = c.getTransferHandler();
                        //tell transfer handler to start drag
                        handler.exportAsDrag(c, firstMouseEvent, action);
                        //reset first mouse event for the next time
                        firstMouseEvent = null;
        }I hope that helps! ;-)
    Any comment is apprechiated!
    Kind regards,
    Patrick

    I'm absolutetly devastated!!
    I spent hours looking for advice on a treetable component after someone mentioned the idea not too long ago, in another thread might I add.
    And I just spent the last 2 damn weeks implementing myy own. I feel heart broken! JTreeTable v1 was even very similar tomy first bash...but I gave on using the JTree as the renderer as it just looked lame... the way I did it anyway.
    So just today I finished my own impl, with a new JComponent derivative soley for the rendering of the tree-like column.
    Any clue as to when they intend to make it a standard JFC Swing component.
    Bloody marvelous! So annoyed as it was a serious road-block to my current project! And asmuch as it was fun, I didn't choose to do for fun. AAAAAAARRRGGH!!
    ps. congratulations, if you feel at all like how I felt half an hour ago, you must be very chuffed.

  • Selection in JTreeTables

    I'm trying to programmatically select nodes within my JTreeTable, with zero-success...
    I imagined the following would be fine for rendering the selection.
    JTree tree = treeTable.getTree();
    tree.setExpandsSelectedPaths(true);
    treePath = treePath.pathByAddingChild(someObject);
    tree.setSelectionPath(treePath);
    The parent node is properly expanded and the new child becomes visible, however, there is no selection.
    Any help very welcome.
    thanks,
    ian

    Hi monicaba!
    I've had the same problem. The Method setSelectionPath() did not do what it should. I read your articles and tried out your suggestion to comment the delayedFireTableDataChanged() line. But it did not solve the problem.
    Anyway, I found another way to make it work and I want to share it with you ;-) :
    After inserting the new node and after updating the display via calling fireTreeNodesInserted(), I return the new tree path to the new child (addChildToParent() is my own method of the tree table model):
    // Insert child into tree table, update the display via
    // fireTreeNodesInserted() and return the new inserted tree path
    _selectionPath = treeTableModel.addChildToParent(...);
    Then I call the invokeLater() method of SwingUtilities to select the new path (Jtretbl_Data is my JTreeTable!):
    // Make the new path selected
    SwingUtilities.invokeLater(new Runnable() {
    public void run() {
    Jtretbl_Data.getTree().setSelectionPath(_selectionPath);
    The disadvantage of this is that the variable _selectionPath has to be a member variable of my applet. Perhaps I could improve that point.
    Best regards,
    Peter

  • JTreeTable+add a password field in it

    Hi All
    I was successful in writing a code for JTreeTable but now I want to add a password field in it which is editable by the users.
    Any help would be appreciated...
    Thanks
    apoorva

    Sorry for the long code that I pasted.
    My issue is this :
    a) I created a renderer and editor for having one column act as a password field.When I used this renderer and editor in a simple JTable it worked well but when i added the same to my JTreeTable code the editor worked fine(I guess!!!) cos when I typed something it showed as hidden characters but on hitting enter key the value would disappear (the renderer messing it up I guess!!! ) :(
    Here is my renderer and editor for JPasswordField
    public static class PasswordTableCellRenderer extends JPasswordField implements TableCellRenderer
    public Component getTableCellRendererComponent(
    JTable table,Object value, boolean isSelected, boolean hasFocus, int row,
    int column) {
    setText((value ==null) ? "" : value.toString());
    return this;
    public class MyEditor extends DefaultCellEditor
    public MyEditor(){super(new JPasswordField());}
    }b) Also the model I use for the JTreeTable extends AbstractTableModel and hence I override the getValueAt() method. I am not understanding how renderer/editor works with this getValueAt() method.
    Hope I am a little clearer this time
    Thanks
    apoorva
    Edited by: apugupt on Jun 20, 2008 8:16 PM

  • JtreeTable - Nodes update issue - Nodes are cut off

    Hi,
    I'vet got a little problem with the JtreeTable. Everything works fine until I try to change the rendering of a row to BOLD.
    The text turns bold, but the TreeNode (first col in row) is cut off because it was first rendered plain and now its to big to be
    displayed.
    I tried
    tree.getModel().valueForPathChanged(new TreePath(node.getPath()), myNewValue);but beacuse value doesn't change (text stays just font changes) there is no need to fireNodesChanged.

    Here's one I put together. Select any node, and any other node with text that begins with the same letter is rendered in bold. From my test, it looks like repaint on the tree isn't sufficient. However, firing node changed events seem to be working (as a quick and dirty measure, I fire node changed on every node each time). Now I have to go back and revisit the problem I originally had and see what I was doing there.
    import java.awt.BorderLayout;
    import java.awt.FlowLayout;
    import javax.swing.*;
    import javax.swing.event.TreeSelectionEvent;
    import javax.swing.event.TreeSelectionListener;
    import javax.swing.tree.*;
    public class BoldTreeCellTest {
         public static void main(String[] args) {
              SwingUtilities.invokeLater(new Runnable() {
                   public void run() {
                        launchUI();
         private static void launchUI() {
              final DefaultMutableTreeNode[] nodes = new DefaultMutableTreeNode[5];
              JFrame frame = new JFrame("Test JTree With Bold Rendering");
              nodes[0] = new DefaultMutableTreeNode("root of the tree here");
              nodes[1] = new DefaultMutableTreeNode("Every cell which has the");
              nodes[2] = new DefaultMutableTreeNode("same first character as the");
              nodes[3] = new DefaultMutableTreeNode("selected cell text will have it's text");
              nodes[4] = new DefaultMutableTreeNode("rendered in bold.");
              for (int i=1; i<nodes.length; i++) {
                   nodes[0].add(nodes);
              final DefaultTreeModel model = new DefaultTreeModel(nodes[0]);
              final JTree tree = new JTree(model);
              final JRadioButton useRepaintButton = new JRadioButton("Repaint Tree", true);
              final JRadioButton useNodesChangedButton = new JRadioButton("Fire Nodes Changed");
              ButtonGroup buttonGroup = new ButtonGroup();
              buttonGroup.add(useRepaintButton);
              buttonGroup.add(useNodesChangedButton);
              tree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() {
                   @Override
                   public void valueChanged(TreeSelectionEvent event) {
                        if (useRepaintButton.isSelected()) {
                             tree.repaint();
                        } else {
                             model.nodeChanged(nodes[0]);
                             model.nodesChanged(nodes[0], new int[] {0, 1, 2, 3});
              tree.setCellRenderer(new BoldTreeCellRenderer());
              JScrollPane pane = new JScrollPane(tree);
              JPanel panel = new JPanel(new BorderLayout());
              JPanel buttonPanel = new JPanel(new FlowLayout());
              buttonPanel.add(useRepaintButton);
              buttonPanel.add(useNodesChangedButton);
              panel.add(buttonPanel, BorderLayout.NORTH);
              panel.add(pane, BorderLayout.CENTER);
              frame.setContentPane(panel);
              frame.pack();
              frame.setLocationRelativeTo(null);
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              frame.setVisible(true);
    import java.awt.Component;
    import java.awt.Font;
    import javax.swing.JLabel;
    import javax.swing.JTree;
    import javax.swing.tree.DefaultMutableTreeNode;
    import javax.swing.tree.DefaultTreeCellRenderer;
    import javax.swing.tree.TreePath;
    public class BoldTreeCellRenderer extends DefaultTreeCellRenderer {
         private Font plainFont;
         private Font boldFont;
         public BoldTreeCellRenderer() {
              super();
              Font baseFont = (new JLabel()).getFont();
              this.plainFont = baseFont.deriveFont(Font.PLAIN);
              this.boldFont = baseFont.deriveFont(Font.BOLD);
         @Override
         public Component getTreeCellRendererComponent(JTree tree, Object value,
                   boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
              super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
              String st = (String) ((DefaultMutableTreeNode) value).getUserObject();
              Font font = this.plainFont;
              TreePath selectionPath = tree.getSelectionPath();
              if (selectionPath != null) {
                   String selectedText = (String) ((DefaultMutableTreeNode) selectionPath.getLastPathComponent()).getUserObject();
                   if (st.startsWith(selectedText.substring(0, 1))) {
                        font = this.boldFont;
              setFont(font);
              return this;
    Edited by: Skotty on Aug 12, 2010 2:02 PM
    Edited by: Skotty on Aug 12, 2010 2:05 PM - set useRepaintButton as selected on start                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

  • Different tooltips in JTreeTable

    Hi all!
    I have a JTreeTable (the rows are the nodes of a tree), very similar to the one at
    http://java.sun.com/products/jfc/tsc/articles/treetable2/
    I'd like to add different ToolTips in every node (in the example in the sun's site, for example see as a tooltip the file's name). How can I do that? Should I do that in the cell render method? Has anybody any example about that?
    Feedbacks are really appreciated!
    Thanks
    Franky

    Sure, sorry for the mistake about the tags...Follows the class I use to render the JTreeTable. My doubt is that I have to do something with the mouse listener to active the tooltip, could it be?
    Thanks
    public class TreeTableCellRenderer
              extends JTree
              implements TableCellRenderer {
              protected int visibleRow;
              protected Border highlightBorder;
              public TreeTableCellRenderer(TreeModel model) {
                   super(model);
              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"));
              public void setRowHeight(int rowHeight) {
                   if (rowHeight > 0) {
                        super.setRowHeight(rowHeight);
                        if (JSortTreeTable.this != null
                             && JSortTreeTable.this.getRowHeight() != rowHeight) {
                             JSortTreeTable.this.setRowHeight(getRowHeight());
              public void setBounds(int x, int y, int w, int h) {
                   super.setBounds(x, 0, w, JSortTreeTable.this.getHeight());
              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;
                   this.setToolTipText("Tooltip");
                   System.out.println("Tooltip "+this.getToolTipText());
                   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");
                   visibleRow = row;
                   setBackground(background);
                   TreeCellRenderer tcr = getCellRenderer();
                   if (tcr instanceof DefaultTreeCellRenderer) {
                        DefaultTreeCellRenderer dtcr = ((DefaultTreeCellRenderer) tcr);
                        if (isSelected) {
                             dtcr.setTextSelectionColor(foreground);
                             dtcr.setTextNonSelectionColor(foreground);
                             dtcr.setBackgroundSelectionColor(background);
                        } else {
                             dtcr.setTextNonSelectionColor(foreground);
                             dtcr.setBackgroundNonSelectionColor(background);
                        Icon tutorialIcon;
                        ImageIcon icon3= new ImageIcon("C:\\eclipse\\workspace\\Java\\itemrevision.gif");
                        tutorialIcon=icon3;
                        dtcr.setOpenIcon((Icon) tutorialIcon);
                        dtcr.setClosedIcon((Icon) tutorialIcon);
                        dtcr.setLeafIcon((Icon) tutorialIcon);
                   return this;
         }

  • How do I use my third computer with cloud. I am rendering a project in Avid Media composer

    How do I get my third computer to work with when I am rendering Avid project on the other two computers computers

    Hi,
    Running creative cloud on third machine will prompt you for the deactivation from last 2 machines. As per EULA for Creative cloud you can only install and work on 2 machines only, be it MAC-MAC, MAC-windows and windows-windows.
    working on third machine without deactivation from previous machines is not possible.
    Hope this helps.
    Thanks
    Kapil Malik

  • Is that a webkit rendering issue in Safari 5.1?

    I add my voice to rendering issues encountered in Safari 5.1, here they are:
    1) Fonts look pixelated on some websites. Here's an example drawn from weebly.
    The font used here is OFL Sorts Mill Goudy, so I guess there must be a font rendering engine in weebly that allows non web safe fonts to be displayed properly. That works fine in Firefox 5 & 6, and until recently on Safari 5. Chrome 12 has exactly the same issue as Safari 5.1, so it could be a general rendering issue in webkit.
    2) Videos on Vimeo show now a black rectangle instead of the video.
    3) The "Insert image" feature in this forum takes forever to load, displaying a white rectangle during several seconds. Same issue with the Evernote clip bookmarklet.
    Hope these issues will be fixed soon, any help is appreciated if something can be changed in Safari settings.
    Note: resetting Safari (including cleaning cache) doesn't solve the described problems. I'm running Snow Leopard 10.6.8 on Mac Pro Quad 2.8 Ghz.

    Thanks for helping diagnose this.
    However, my testing indicates that this is not a bug with border-collapse: collapse. Here is why:
    If I change the value of border-collapse to "separate" and add "border-spacing: 0", the bug remains. To try this, request http://www.panlex.org/cgi-bin/plxu28-bug2.cgi .
    If I leave the value of border-collapse unchanged but change the button elements in the cells to plain text, the bug disappears. To try this, request http://www.panlex.org/cgi-bin/plxu28-bug1.cgi .
    On the basis of this testing, it would seem to me that the bug is dependent on the button elements and independent of the border-collapse CSS attribute.
    This doesn't explain, however, why you have found border-collapse: collapse producing slow results with other large tables and it doesn't do so with my table in http://www.panlex.org/cgi-bin/plxu28-bug1.cgi . It also doesn't explain why you saw the bug disappear when you changed border-collapse on my page but I didn't see it disappear.
    Any further diagnostic help would be welcome.

Maybe you are looking for