I'm trying to wrap lines in Jtree nodes, I found this code which is working good for me but a with a minute defect. On selecting Jtree node, only second half of the text is highlighted in blue leaving first few characters, I tried a lot to fix this but couldn't suceed. Any help regarding it would be really helpful for me.

thank in adavance

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.font.FontRenderContext;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextAttribute;
import java.awt.font.TextHitInfo;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import javax.swing.plaf.ColorUIResource;
import javax.swing.BorderFactory;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.tree.DefaultTreeCellRenderer;

public class WrappedCellRenderer extends DefaultTreeCellRenderer {

    AttributedString as;

    private int anchorEnd;

    private int activeEnd;
    Rectangle2D bounds;
    float px, py, pw, ph;
    float cx, cy; /* Center X, Y */
    float ox, oy; /* Origin X, Y */   
    private static final long serialVersionUID = -3452124074088778903L;
    public Component getTreeCellRendererComponent(JTree tree, Object value,
            boolean isSelected, boolean expanded, boolean leaf, int row, boolean hasFocus) {

        super.getTreeCellRendererComponent(tree, value, isSelected, expanded, leaf, row, hasFocus);
        final String stringValue = tree.convertValueToText(value, isSelected,
                expanded, leaf, row, hasFocus);

        return this;
    TextLayout textLayout;
    private String text;
    private Insets margin = new Insets(3,3,3,3);
    private int maxWidth = Integer.MAX_VALUE;
    private boolean justify;

    private final FontRenderContext frc = new FontRenderContext(null, true, false);

    private void morph() {

    public String getText() {
        return text;

    public void setText(String text) {
        String old = this.text;
        this.text = text;
        firePropertyChange("text", old, this.text);
        if ((old == null) ? text!=null : !old.equals(text))

    public int getMaxWidth() {
        return maxWidth;
    void setSelect(boolean isSelected) 
                Color bColor;
        if (isSelected) {

            bColor = UIManager.getColor("Tree.selectionBackground");
        } else {
            bColor = UIManager.getColor("Tree.textBackground");
     public void setBackground(Color color) {
            if (color instanceof ColorUIResource)
              color = null;
    void setFocus(boolean hasFocus) {
        if (hasFocus) {
             Color lineColor = UIManager
        } else {
            setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
    public void setMaxWidth(int maxWidth) {

        int old = this.maxWidth;
        this.maxWidth = maxWidth;
        firePropertyChange("maxWidth", old, this.maxWidth);
        if (old !=  this.maxWidth)

    public boolean isJustified() {
        return justify;

    public Dimension getPreferredSize() {
        return paintOrGetSize(null, getMaxWidth());

    protected void paintComponent(Graphics g) {

        paintOrGetSize((Graphics2D)g, getWidth());
    public void dimChanged()
    public int getRowHeight()
        return getPreferredSize().height;
    private Dimension paintOrGetSize(Graphics2D g, int width) {
        Insets insets = getInsets();
        Font f = ExpandingPanels.nodeid.getFont();
        width -= insets.left + insets.right + margin.left + margin.right;
        float w = insets.left  + insets.right + margin.left + margin.right;
        float x = insets.left  + margin.left, y=insets.top + margin.top;
        if (width > 0 && text != null && text.length() > 0) {
            as = new AttributedString(getText());

            as.addAttribute(TextAttribute.FONT, f);
            as.addAttribute(TextAttribute.FOREGROUND, Color.BLACK);
        //  as.addAttribute(TextAttribute.BACKGROUND, test.p6.getBackground());

            AttributedCharacterIterator aci = as.getIterator();
            LineBreakMeasurer lbm = new LineBreakMeasurer(aci, frc);
            float max = 0;
            while (lbm.getPosition() < aci.getEndIndex()) {

                textLayout = lbm.nextLayout(width);

                if (g != null && isJustified() && textLayout.getVisibleAdvance() > 0.80 * width)
                    textLayout = textLayout.getJustifiedLayout(width);
                if (g != null)

                    textLayout.draw(g, x, y-2 + textLayout.getAscent());


                y += textLayout.getDescent() + textLayout.getLeading() + textLayout.getAscent();
                max = Math.max(max, textLayout.getVisibleAdvance());
            w += max;
            System.out.println(w+"           "+max);


        /*  addMouseListener(new SelectionMouseListener());
        addMouseMotionListener(new SelectionMouseMotionListener());*/
        return new Dimension((int)Math.ceil(w), (int)Math.ceil(y-6) + insets.bottom + margin.bottom);

3 Years
Discussion Span
Last Post by srikanth2321
  • right there is with Renderer in some cases not starting higlighter and its painting for begining of node, but starting where close parent ended

  • for future readers post ans SSCCE, short, runnable, compilable demonstrated a.m. defect from renderer, and with hadcoded value for Nodes

Edited by mKorbel

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.