Hi,

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;
    @Override
    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);
        setText(stringValue);
        //setBackground(test.p6.getBackground());
        setEnabled(tree.isEnabled());
        setSelect(isSelected);
        setFocus(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() {
        revalidate();
        repaint();
    }

    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))
            morph();
    }

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

            bColor = UIManager.getColor("Tree.selectionBackground");
        } else {
            bColor = UIManager.getColor("Tree.textBackground");
        }
        super.setBackground(bColor);
    }
     public void setBackground(Color color) {
            if (color instanceof ColorUIResource)
              color = null;
            super.setBackground(color);
          }
    void setFocus(boolean hasFocus) {
        if (hasFocus) {
             Color lineColor = UIManager
                        .getColor("Tree.selectionBorderColor");
            setBorder(BorderFactory.createLineBorder(lineColor));
        } 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)
            morph();
    }

    public boolean isJustified() {
        return justify;
    }


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



    protected void paintComponent(Graphics g) {
        //super.paintComponent(g);

        paintOrGetSize((Graphics2D)g, getWidth());
    }
    public void dimChanged()
    {
        setText(text);
        morph();
    }
    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);
    }

}
  • 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 3 Years Ago by mKorbel

This question has already been answered. Start a new discussion instead.