JTree, CellRenderer + abgeschnitt. Text

benhaze

Mitglied Platinum
Hallo!

Ich habe folgendes Problem:

Ich hab nen normalen JTree.
diesem habe ich meinen TreeCellRenderer untergeschoben...
die methode getTreeCellRendererComponent(...) liefert halt eine geeignete Komponente zum Darstellen des Knotens im Baum.

Wenn es sich um einen bestimmten Knoten handelt, soll er einfach den Text im Baum
*fett* darstellen.
Das klappt auch. Allerdings wird durch das *fett* darstellen, der Text in seiner Dimension dadurch etwas größer, das Label (welches den Text darstellt) allerdings nicht.
Der Text wird also quasi abgeschnitten.

Hat evtl. jemand ne idee, was ich da machen kann?
(Hatte an sowas gedacht wie myTree.validate()...klappt aber nicht....)

Danke!

Code:
    public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus)
    {
        Component ret = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
        
        if (value instanceof MyTreeNode)
        {
            JLabel lbl = (JLabel)ret;
            MyTreeNode node = (MyTreeNode)value;
            if (node.getListDetailAsClonePanel() != null)
            {
                String text = lbl.getText();
                String boldText = "<html><b>"+ text +"</b></html>";
                lbl.setText(boldText);
            }

            ImageIcon icon = node.getIcon();
            if (icon != null)
                lbl.setIcon(icon);
        }
        
        return ret;
    }
 
Hallo,

versuch doch, anstatt HTML String zu erzeugen, den Font des Labels zu verändern:
Java:
Font font = lbl.getFont().deriveFont(Font.BOLD);
lbl.setFont(font);
lbl.setText(text);

Grüße
Vincent
 
Danke für deine Antwort..

Ich habe es gerade getestet.

Ergebnis:

1. alle Nodes (bzw. deren Text) werden nun FETT dargestellt.
2. alle Node-Texte werden mit ... (3 Punkten) beendet. (da der Text nun länger ist als zuvor)

aus *Hallo* wurde *Hal...*

das Label ändert sein Größe (width) einfach nicht.
 
Hallo,

ich habe hier ein kleines Beispiel, da scheint es korrekt dargestellt zu werden, d.h. die Labels werden nicht abgeschnitten:
Java:
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.net.MalformedURLException;
import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeCellRenderer;

/**
 * The Class TreeTest.
 */
public class TreeTest extends JFrame {

    /**
     * Create a new instance of <code>TreeTest</code>.
     */
    public TreeTest() {
        super("TreeTest");
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        final JTree tree = new JTree();
        tree.setCellRenderer(new TreeRenderer());
        getContentPane().add(new JScrollPane(tree));
    }

    /**
     * The Class TreeRenderer.
     */
    private class TreeRenderer extends DefaultTreeCellRenderer {
        /** The default font. */
        private Font defaultFont;

        /** {@inheritDoc} */
        @Override
        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel,
                boolean expanded, boolean leaf, int row, boolean hasFocus) {
            if (defaultFont == null) {
                defaultFont = getFont();
            }
            final JLabel label = (JLabel) super.getTreeCellRendererComponent(tree, value, sel,
                    expanded, leaf, row, hasFocus);
            if (leaf) {
                final Font boldFont = defaultFont.deriveFont(Font.BOLD);
                label.setFont(boldFont);
                try {
                    final URL iconUrl = new URL("http://wikis.sun.com/download/attachments/16418233/gold-star.gif");
                    if (iconUrl != null) {
                        final ImageIcon icon = new ImageIcon(iconUrl);
                        label.setIcon(icon);
                    }
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                }
            } else {
                label.setFont(defaultFont);
            }
            return label;
        }
    }

    /**
     * The main method.
     *
     * @param args the arguments
     */
    public static void main(String[] args) {
        final JFrame frame = new TreeTest();
        final Dimension frameSize = new Dimension(400, 250);
        frame.setSize(frameSize);
        final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        final int frameX = (screenSize.width - frameSize.width) / 2;
        final int frameY = (screenSize.height - frameSize.height) / 2;
        frame.setLocation(frameX, frameY);
        frame.setVisible(true);
    }
}
Vielleicht kann es dir weiterhelfen.

Grüße
Vincent
 
Danke für deine Bemühungen!

Aber das Problem ist das *nachträgliche* ändern der Schrift in FETT.

Ich habe mal ein Beispiel erstellt.

Code:
import java.awt.event.ActionEvent;
import javax.swing.*;
import java.awt.*;
import javax.swing.tree.*;

public class TestTree {

    private static class TreeNodeEx extends DefaultMutableTreeNode
    {
        private boolean m_isBold;

        private TreeNodeEx(String string) {
            super(string);
        }

        public boolean isBold() {
            return m_isBold;
        }

        public void setBold(boolean p_isBold) {
            this.m_isBold = p_isBold;
        }
       
    }
   
        public static void main(String[] args) {
                TreeNodeEx rootNode = new TreeNodeEx("root");

                try{UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());}catch(Exception ex){}
               
                for(int i=0; i<5;i++) {
                        TreeNodeEx level1Node = new TreeNodeEx("Level 1 Node " + i);
                        for(int k=0; k<5; k++) {
                                TreeNodeEx level2Node = new TreeNodeEx("Level 2 Node " + i + "." + k);
                                level1Node.add(level2Node);
                        }
                        rootNode.add(level1Node);
                }

                final JTree tree = new JTree(rootNode);
                tree.setPreferredSize(new Dimension(500, 500));
                tree.setCellRenderer(new DefaultTreeCellRenderer() {
                    public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
                        Component ret = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
                       
                        JLabel lbl = (JLabel)ret;

                        TreeNodeEx node = (TreeNodeEx)value;
                        if (node.isBold())
                        {
                            String text = lbl.getText();
                            String boldText = "<html><b>"+ text +"</b></html>";
                            lbl.setText(boldText);
                        }
                        return lbl;
                    }
                });               

                JScrollPane scrl = new JScrollPane(tree);
               
                JPanel centerPanel = new JPanel();
                centerPanel.setPreferredSize(new Dimension(500, 500));

                 Action a = new AbstractAction("Node Fett!") {

                        public void actionPerformed(ActionEvent e) {
                            TreePath tp = tree.getSelectionPath();
                            if (tp != null)
                            {
                                TreeNodeEx node = (TreeNodeEx)tp.getLastPathComponent();
                                node.setBold(!node.isBold());
                                tree.repaint();
                            }
                        }
                    };
                JButton button = new JButton(a);
               
                JFrame frame = new JFrame();
                frame.getContentPane().setLayout(new BorderLayout());
                frame.getContentPane().add(centerPanel, BorderLayout.CENTER);
                frame.getContentPane().add(button, BorderLayout.EAST);
                frame.getContentPane().add(scrl, BorderLayout.WEST);
                frame.setSize(800,600);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

        }


}

Das Problem ist das die PrefferedSizes der Labels, beim ersten Laden gecached werden.
 
also wenn dem Tree gesagt wird, es habe nen *LargeModel*, dann geht es.

Code:
...
JTree tree = new JTree();
tree.setLargeModel(true);
...
 
Hallo,

ersetze in actionPerformed() Methode die Zeile
Java:
tree.repaint();
durch
Java:
tree.updateUI();
dann werden die Labels richitg dargestellt.

Grüße
Vincent
 
Super!
updateUi() funktioniert auch.

Das Problem hierbei (für mich):
Nach jedem Node.setBold(true/false) müsste ich
selber dafür sorgen, das updateUi() aufm Tree aufgerufen wird.
(updateUi in getTreeCellRendererComponent aufrufen, ist nicht so gut :rolleyes:)

mit setLargeModel() ist das nicht der Fall.

Nachteil an setLargeModel() -> alle Rows müssen (oder werden) die gleiche Höhe haben.
(in meinem Fall, kein Problem)

Danke nochmal
 
Zurück