set different jtree row heights dynamically

2.1k views Asked by At

All,

Spent last two days trying to dynamically set different row heights for a JTree but zero success. Below is an image of what I'm trying to achieve... Here's what I have tried:

(1) using setRowHeight(0) so the node would query it's current cell renderer

(2) setting the PreferredSize(Dimension d) of the component returned from the jtree's cell renderer.

(3) changing the rowheight in the renderer itself which I understand now shouldn't be done.

I don't see how I set a different cell renderer on the same column e.g. column A below where maybe i could hardcode a different row height.

enter image description here

Anyone got any tips or tricks or better still a working example, my head is fried and I seem to have exhausted all other resources.. this should be possible,right?

1

There are 1 answers

2
aterai On

(1) and (2) works fine for me using JDK1.8.0_51 on Windows 10:

enter image description here

import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;

public class RowHeightsDynamicallyTest {
  public JComponent makeUI() {
    JTree tree = new JTree() {
      @Override public void updateUI() {
        setCellRenderer(null);
        super.updateUI();
        setCellRenderer(new RowHeightsDynamicallyRenderer());
        setRowHeight(0);
        setRootVisible(false);
        setShowsRootHandles(false);
      }
    };
    return new JScrollPane(tree);
  }
  public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        createAndShowGUI();
      }
    });
  }
  public static void createAndShowGUI() {
    try {
      for (UIManager.LookAndFeelInfo laf: UIManager.getInstalledLookAndFeels()) {
        if ("Nimbus".equals(laf.getName())) {
          UIManager.setLookAndFeel(laf.getClassName());
        }
      }
    } catch (ClassNotFoundException | InstantiationException
               | IllegalAccessException | UnsupportedLookAndFeelException ex) {
      ex.printStackTrace();
    }
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f.getContentPane().add(new RowHeightsDynamicallyTest().makeUI());
    f.setSize(320, 240);
    f.setLocationRelativeTo(null);
    f.setVisible(true);
  }
}

class RowHeightsDynamicallyRenderer extends DefaultTreeCellRenderer {
  private int height;
  @Override public Component getTreeCellRendererComponent(
      JTree tree, Object value, boolean selected,
      boolean expanded, boolean leaf, int row, boolean hasFocus) {
    JLabel l = (JLabel) super.getTreeCellRendererComponent(
        tree, value, selected, expanded, leaf, row, hasFocus);
    l.setFont(tree.getFont().deriveFont(leaf ? 16f : 48f));

    height = leaf ? 20 : 60;
    //use dummy height Icon: l.setIcon(new DummyHeightIcon(height));
    //use <td> height: l.setText(String.format("<html><table><tr><td height='%d'>%s", height, value));
    return l;
  }
  @Override public Dimension getPreferredSize() {
    Dimension d = super.getPreferredSize();
    d.height = height;
    return d;
  }
}

// class DummyHeightIcon implements Icon {
//   private final int height;
//   public DummyHeightIcon(int height) {
//     this.height = height;
//   }
//   @Override public void paintIcon(Component c, Graphics g, int x, int y) {}
//   @Override public int getIconWidth() {
//     return 0;
//   }
//   @Override public int getIconHeight() {
//     return height;
//   }
// }