Multipe Font in a JTree

Hello,
I want some paticular nodes appear in Bold font and all the others in normal font.
I subclass DefaultTreeRenderer with this code :
public class ArbreComposantRenderer extends DefaultTreeCellRenderer {
Font _f;
ImageIcon racineIcone,otherIcone;
//police de caractere utilis�es
protected Font normalFont = UIManager.getFont("Label.font");
protected Font myFont = normalFont.deriveFont(Font.BOLD);
public ArbreComposantRenderer() {
//initialisation des icones
_racineIcone = new ImageIcon(this.getClass().getResource("images/modeles.gif"));
otherIcone = new ImageIcon(this.getClass().getResource("images/sousmodele.gif"));
public Component getTreeCellRendererComponent(JTree tree,Object value,boolean sel,boolean expanded,boolean leaf,int row,boolean hasFocus) {
super.getTreeCellRendererComponent(tree, value, sel,expanded, leaf, row,hasFocus);
if(row==0){
setIcon(_racineIcone);
else{
if(isIdentifiant(value)){
setFont(myFont);
setIcon(_therIcone);
return this;
protected boolean isIdentifiant(Object value){
DefaultMutableTreeNode noeud = (DefaultMutableTreeNode)value;
Object noeudObjet = noeud.getUserObject();
if(noeudObjet instanceof Attribut){
Attribut a = (Attribut) noeudObjet;
noeud = (DefaultMutableTreeNode) noeud.getParent();
Composant c = (Composant)noeud.getUserObject();
if(c.getIdentifiant()==a){
return true;
return false;
this doesn't work.
When no node "Identifiant" is visible all the nodes are painted in normal font and when a node "Identifiant" is visible all the nodes are painted bold font.
Can any body tell me how to solve my problem.
Thanks.
fleur.

Found a solution under this threa in the Project Swing [Archive]:
JTable's header : changing font , help help
Author: ssyca
In Reply To: JTable's header : changing font , help help
It suggests calling the overridden method in the DefaultCellRenderer, catching the returned Component, then setting values on that Component before finally returning it at the end of the overriding method!!
Search on the above title, and all will be clear...
I would be very interested in the answer to this too,
as I'm trying to do exactly the same thing!!!
Is swing really as horrible as it tries to make us
believe it is???!!
Cheers,
Stephen Hobdell

Similar Messages

  • Change font size of JTree nodes dynamically

    hi,
    I have a requirement to change the font size of nodes in a JTree as and when the user wants.
    I have implemented a custom renderer for the JTree, but right now i have a fixed font size for all the nodes.
    How can I change the font size of JTree at runtime??
    thanks.

    I haven't done this, but it seems like
    public Component getTreeCellRendererComponent(...Object value,...) {
    Component c = super.getTreeCellRendererComponent(...);
    if (value!=null &&
    value instanceof(String) &&
    ((String)value).startsWith("A")) {
    c.setFont(bigFont);
    else c.setFont(littleFont);
    }It seems that this code is just making the font size of nodes begining with "A" bigger and the rest smaller.
    It doesn't solve my problem.
    I want to have something like a font chooser by which user can choose the font size they want for the JTree.
    any help ??

  • The font in my JTree

    I was wondering if anyone could tell me how to change my JTree font (the node labels) to a fixed-width font, or how to use a font which is naturally fixed-width?
    Thanks,
    Jamie.

    You have to override default TreeCellRenderer with any specified font.
    regards
    Stas.

  • About font of JTree

    Hi,
    Actually I want to change the font of a jTree and when I clicked save button in jDialog containing combobox for Font size ,style,name.I already mentioned in another class the default value so can u some one help me to change the font dynamically?

    actually I want to change whole JFrame font when I switch to Look and feel all cobobox containg font name ,size and style shud be disabled except java look anfd feel.ya font works

  • Jtable set cell Font and Color depending on JTree selection

    Hello all,
    I have the following problem:
    A JTree displays certain values. On selection of one value in the JTree I would like to mark certain cells in a JTable. For instance: If value1 is selected in the tree, set bold font in cell1, cell2 and cell3. If value2 is selected in the tree, set bold font in cell35 and cell36.
    I have a renderer that sets my default font, color, foreground and background, but how I set now dynamically single cells in the JTable. I would accept a solution where instead of changing the font in a cell to bold, the cells will be selected.
    Thank you for any replies,
    lexdabear

    I'm looking too... If you found the solution to just change the font to a specific cell? please shared...

  • JTree how to use different font's color for different node

    Hi all
    This is the first time I am using JTree in my application and I have got some problems with it that I can't work out after reading the Java tutorial. Please help!
    1. For some nodes, the font color need to be different.
    2. One node need to use more than one font type for example "This is a sample " some words need to be bolded.
    Kind regards
    Edmond

    Did you read the section on [url http://java.sun.com/docs/books/tutorial/uiswing/components/tree.html#display]Customizing a Tree's Display?
    And did you follow the link on renderers?

  • JTree, wont to change Font

    I want to change the Font of JTree.
    I use:
    class MyLabelRenderer extends DefaultTreeCellRenderer{
           public Component getTreeCellRendererComponent(JTree tree, Object value,
               boolean sel, boolean expanded, boolean leaf, int row,
               boolean hasFocus){
             super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf,
                 row, hasFocus);
                        setFont(getFont().getFontName(),getFont().getStyle(),myNewFontSize);
                        return this;
    }then the Fontsize has changed. If 'myNewFontSize' is lager than old Fontsize, the Label become to short at the end and cut the value to '...'. What's wrong?

    works fine for me.
    instead of this
    setFont(getFont().getFontName(),getFont().getStyle(),myNewFontSize);all you need is
    deriveFont(float size)
    e.g. for a JLabel
    label.setFont(label.deriveFont(24f));[edit]
    actually should be
    label.setFont(label.getFont().deriveFont(24f));Edited by: Michael_Dunn on 8/06/2008 09:46

  • HELP ! HOW CAN I CHANGE JTREE FONT DYNAMICALLY ?

    WHEN I CLICK ON A JTREE NODE THAT NODE MUST TO CHANGE FONT .
    HOW CAN I DO IT ?

    implement ur own treecellrenderer class in the following way:
    yourTree.setCellRenderer(new MyTreeCellRenderer());
    class MyTreeCellRenderer extends DefaultTreeCellRenderer {
          public Component getTreeCellRendererComponent( JTree tree,
                                                         Object value,
                                                         boolean sel,
                                                         boolean expanded,
                                                         boolean leaf,
                                                         int row,
                                                         boolean hasFocus )
             Component component =
                     super.getTreeCellRendererComponent(
                         tree, value, sel, expanded, leaf, row, hasFocus);
             if(sel) {
                Font dynamicFont =
                  // put here the output font of conditional evaluation
                component.setFont(dynamicFont);
             } else {
                // if u want the default font when node is deselected
                // then uncomment the following code
                //component.setFont(null);
             return component;
    }hope this helps u, this code works fine in my program, but i face problem in resizing of the cell when font size is greater then the one earlier.
    regards,
    Afroze.

  • JTree Set Font

    I used the DefaultTreeCellRenderer setFont to change the font for my tree display. The font appears correctly, but the tree text was displayed with "...". It displayed the full text when expanded, but the root entry remains abbreviated and I haven't been able to change it. Is there another property to change to force it to display the full name?

    here is the solution:
    new DefaultTreeCellRenderer() {
                                                                        public Color getTextNonSelectionColor() {
                                                                            return Color.red; } });thank you

  • Problem with JTree editing icons

    Hello,
    I want to edit another icons than the default icons in JTree object.
    I look in the javadoc at the several methods, but I do not find a method witch can give me the possibility to setup the collapsed and expanded icon.
    If some one now how to do that, it will be cool.
    Thanks.

    I write this class :
    public class SampleTreeCellRenderer extends TreeCellRenderer
    /** Font used if the string to be displayed isn't a font. */
    static protected Font defaultFont;
    /** Icon to use when the item is collapsed. */
    static protected ImageIcon collapsedIcon;
    /** Icon to use when the item is expanded. */
    static protected ImageIcon expandedIcon;
    /** Color to use for the background when selected. */
    static protected final Color SelectedBackgroundColor=Color.yellow;
    static
         try {
         defaultFont = new Font("SansSerif", 0, 12);
    } catch (Exception e) {}
         try {
         collapsedIcon = new ImageIcon("images/collapsed.gif");
         expandedIcon = new ImageIcon("images/expanded.gif");
         } catch (Exception e) {
         System.out.println("Couldn't load images: " + e);
    public SampleTreeCellRenderer() {
    super();
    public SampleTreeCellRenderer(String collapsedImagePath,String expandedImagePath) {
    super();
         try {
         if (collapsedImagePath!=null) collapsedIcon = new ImageIcon(collapsedImagePath);
         if (expandedImagePath!=null) expandedIcon = new ImageIcon(expandedImagePath);
         } catch (Exception e) { System.out.println("Couldn't load images: " + e); }
    public void setCollapsedIcon(String path) {
    try {
    if (path!=null) collapsedIcon=new ImageIcon(path);
    } catch (Exception e) { System.out.println("Couldn't load images: " + e); }
    public void setExpandedIcon(String path) {
    try {
    if (path!=null) expandedIcon=new ImageIcon(path);
    } catch (Exception e) { System.out.println("Couldn't load images: " + e); }
    /** Whether or not the item that was last configured is selected. */
    protected boolean selected;
    public Component getTreeCellRendererComponent(
    JTree tree, Object value,     
    boolean selected, boolean expanded,
    boolean leaf, int row, boolean hasFocus) {
         Font font;
         String stringValue = tree.convertValueToText(value, selected,expanded,leaf,row,hasFocus);
         /* Set the text. */
         setText(stringValue);
         /* Tooltips used by the tree. */
         setToolTipText(stringValue);
         /* Set the image. */
         if(expanded) { setIcon(expandedIcon); }
         else if(!leaf) { setIcon(collapsedIcon);}
    else { setIcon(null);}
         /* Update the selected flag for the next paint. */
         this.selected = selected;
         return this;
    public void paint(Graphics g) {
         super.paint(g);
    } // end of class SampleTreeCellRenderer
    I test it but I do not understand why it do not display the icons.

  • 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 - node text doesn't fit when shown with icon

    When I start off my JTree with a long string text for the node (without any icon...used setLeafIcon( null )... it displays fine. But during the execution of hte program an icon may appear next to a particular node - but when this happens, the icon displays fine and the text of the node is cut off (you just see a couple letters followed by the usual "...").
    Any ideas?

    Thanks for the reply. I am not sure how to use that for what I'm doing...basically I am writing an AIM clone. And when a user sets an away message, I want an icon to appear next to their name, otherwise the icon is set to null. Here is the code I have right now for my tree cell renderer class (the tree class is a basic tree):
    import javax.swing.*;
    import javax.swing.event.*;
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.tree.*;
    import javax.swing.text.*;
    import java.util.*;
    import java.io.*;
    class MyTreeCellRenderer extends DefaultTreeCellRenderer {
         * Handle to the ClientTree.
        ClientTree clientTreeObj;
         * Constructor.
        public MyTreeCellRenderer( ClientTree ct ) {
            clientTreeObj = ct;
         * Gets the cell renderer for the current object
         * in the tree.
        public Component getTreeCellRendererComponent(
            JTree tree,
            Object value,
            boolean sel,
            boolean expanded,
            boolean leaf,
            int row,
            boolean hasFocus) {
        super.getTreeCellRendererComponent(
            tree, value, sel,
            expanded, leaf, row,
            hasFocus);
        // if we are at the root, take away the icons and set
        // the appropriate font.
        if (!leaf) {
            setClosedIcon( null );
            setOpenIcon( null );
            setToolTipText( null );
            setFont( new Font( "SansSerif", Font.BOLD, 14 ) );
        // we are at a leaf, so set the tooltip to be the username and
        // set the appropriate font.
        else {
            // make sure we are not at the "Users" node
            if ( !value.toString().equals( "Users" ) ) {
                // if the client has an away message, set the icon to a note icon
                if ( clientTreeObj.getJCC().getClientAwayMessage( value.toString() ).length() > 0 ) {
                    System.out.println( value.toString() + ": has a message..." );
                    setLeafIcon( new ImageIcon( "C:/JavaChat/JavaClient/images/message.jpg" ) );
                    ((DefaultTreeModel)tree.getModel()).nodeChanged((DefaultMutableTreeNode)tree.getPathForRow(row).getLastPathComponent() );
                    //tree.fireTreeExpanded( tree.getPathForRow( row ) );
                else {
                    setLeafIcon( null );
                    //tree.fireTreeExpanded( tree.getPathForRow( row ) );
                // get the connection time for the selected user
                // I TOOK OUT THE CODE TO CALCULATE THE TIME BECAUSE IT IS UNIMPORTANT AND LONG :)
                // set the tooltiptext to include the username and the online time
                String tooltip = " " + value.toString() + '\n' + "   Online time:" + '\t';
                    // days
                    if ( days > 0 ) {
                        if ( days == 1 )
                            tooltip += days + " day, ";
                        else
                            tooltip += days + " days, ";
                    // hours
                    if ( hours > 0 ) {
                        if ( hours == 1 )
                            tooltip += hours + " hour, ";
                        else
                            tooltip += hours + " hours, ";
                    // minutes (we always print at least 1)
                    if ( minutes > 1 )
                        tooltip += minutes + " minutes ";
                    else
                        tooltip += minutes + " minute ";
                    setToolTipText( tooltip );
                    setFont( new Font( "SansSerif", Font.PLAIN, 14 ) );
            return this;
        } // end getTreeCellRendererComponent
    } // end class MyRenderer

  • Display tree in JTree

    Hi, I would like to ask you how can I display my Tree? in JTree?
    I create tree:
    Folder fol = new Folder(folderName, numFiles);
    DefaultMutableTreeNode treeNode = new DefaultMutableTreeNode(fol);
    ....But now I does not know how to display tree with folder names. When I use tree.setModel(...); it display object, but not folder names...
    And how can I use red font color for folder names with 0 files(numFiles = 0)?

    Hi, I would like to ask you how can I display my
    Tree? in JTree?
    I create tree:
    Folder fol = new Folder(folderName, numFiles);
    DefaultMutableTreeNode treeNode = new
    DefaultMutableTreeNode(fol);
    ....But now I does not know how to display tree with
    folder names. When I use tree.setModel(...); it
    display object, but not folder names...you need to walk through your tree and create a new DefaultMutableTreeNode for each of your nodes and add to its parent node of your JTree (remember there is a distinction between view and control). the user object of your DefaultMutable TreeNodes is the file/folder, which should be in its own class (see below) and overwrite toString() to return the name. then the JTree will show what you want.
    >
    And how can I use red font color for folder names
    with 0 files(numFiles = 0)?you need a tree cell renderer. it gets your file/folder object (see above) as a parameter. you can query it about the number of files and set the foreground/background accordingly.
    thomas

  • How do I make nodes in my JTree render as JTextPanes ?

    As a newbie to Java, I developed an application which started out by by having a user select a value in a JList and associated information was formatted nicely into a JTextPane (really it is just making some bold/italic/regular font switches).
    I now think it may be more visually appealing to represent the whole thing as a JTree, and the user would just click the +/- to access the associated information.
    So I would like substitute the JTree for the JList, while keep my nicely formatted JTextPane and am a bit stuck. I'd like each item in the JList to be a node and the information is going to be a leaf.
    Searching through the forums and other tutorials it I think I need to create a TreeCellRenderer that uses my JTextPane.
    Aside from advice such as Prior Planning Prevents Poor Performance, can someone give me a gentle kick in the right direction ? Pseudo-code or links would be great !
    Thanks in advance.

    Hi codingMonkey,
    I've looked at both of those (previously) but I've not got enough experience to figure out the coding bits for my application.
    So lets say I wanted to hack the JTextPane example here http://java.sun.com/docs/books/tutorial/uiswing/components/editorpane.html and put a simple JTree in its place with three nodes and use the provided JTextPane as a text for the leafs.
    I think the important bits (except are addStylesToDocument) are this:
    private JTextPane createTextPane() {
            String[] initString =
                    { "This is an editable JTextPane, ",            //regular
                      "another ",                                   //italic
                      "styled ",                                    //bold
                      "text ",                                      //small
                      "component, ",                                //large
                      "which supports embedded components..." + newline,//regular
                      " " + newline,                                //button
                      "...and embedded icons..." + newline,         //regular
                      " ",                                          //icon
                      newline + "JTextPane is a subclass of JEditorPane that " +
                        "uses a StyledEditorKit and StyledDocument, and provides " +
                        "cover methods for interacting with those objects."
            String[] initStyles =
                    { "regular", "italic", "bold", "small", "large",
                      "regular", "button", "regular", "icon",
                      "regular"
            JTextPane textPane = new JTextPane();
            StyledDocument doc = textPane.getStyledDocument();
            addStylesToDocument(doc);
            try {
                for (int i=0; i < initString.length; i++) {
                    doc.insertString(doc.getLength(), initString,
    doc.getStyle(initStyles[i]));
    } catch (BadLocationException ble) {
    System.err.println("Couldn't insert initial text into text pane.");
    return textPane;
    I don't really understand the TreeCellRenderer API link you sent and how to link the above JTextPane to the TreeCellRenderer.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

  • Help setting node height in a JTree

    I have a JTree in which i would like to make the font of the nodes somewhat large (size 16). However, by setting the node's font to this size, i notice that the top and bottom of the node values are truncated. I was wondering how i could increase each node's height so that the value can be easily readable. I have tried extending DefaultTreeCellRenderer and setting the preferred and minimun sizes. I have also tried using a panel as my TreeCellRenderer and setting its sizes. Neither of these attempts worked. So, does anyone out there know how to set the node height or node spacing of a JTree?

    When I set the font on the JTable, everything seems to scale well.

Maybe you are looking for