Java JTree:可变行高

Java JTree:可变行高,java,swing,jtree,row-height,Java,Swing,Jtree,Row Height,我希望我的JTree具有可变的行高。从我所读到的内容来看,我所要做的就是setRowHeight(0)并实现一个自定义TreeCellRenderer。在TreeRenderer中,根据项目设置不同的边框。但是,添加边框时,行高度仍然保持不变。例如,添加EmptyBorder(0,0,8,0)时,标签会向顶部移动8个像素。因此,与左侧的预期结果不同,右侧的树类似: EXPECTED: RESULT: _ _ |-|_| Item

我希望我的JTree具有可变的行高。从我所读到的内容来看,我所要做的就是
setRowHeight(0)
并实现一个自定义
TreeCellRenderer
。在TreeRenderer中,根据项目设置不同的边框。但是,添加边框时,行高度仍然保持不变。例如,添加
EmptyBorder(0,0,8,0)
时,标签会向顶部移动8个像素。因此,与左侧的预期结果不同,右侧的树类似:

  EXPECTED:          RESULT:
     _                 _
  |-|_| Item 1      |-|_| Item 1
  |  _              | |_| Item 2  
  |-|_| Item 2      |-
  |                 |  _
  |  _              |-|_| Item 3
  |-|_| Item 3      
这基本上是我的代码:

JTree tree = new MyTree(root);

class MyTree extends JTree{
   public MyTree(DefaultMutableTreeNode root){
     super(root);
     setCellRenderer(new CustomCellRenderer());
     setRowHeight(0);
}

class CustomCellRenderer extends DefaultTreeCellRenderer {

@Override
public Component getTreeCellRendererComponent(JTree tree, Object value,
        boolean isSelected, boolean expanded, boolean leaf, int row,
        boolean hasFocus) {

        JComponent c = (JComponent) super.getTreeCellRendererComponent(tree, value, isSelected, expanded, leaf, row, hasFocus);
        Data d = (Data)((DefaultMutableTreeNode) value).getUserData();  
        int bttm = 0;
        if(d.isTrue()){
            bttm = 8;
        }
        c.setBorder(BorderFactory.createEmptyBorder(0, 0, bttm, 0));

        //setting size didn't show any effect either: 
        //c.setPreferredSize(new Dimension(150, 16+bttm));
        return c; 
    }

}

您的假设是错误的,排高没有保持不变。行高是行的顶部和底部之间的距离,换句话说,是行上方和下方行之间的占用空间。你的草图清楚地显示了一个上升的距离,这就是真正发生的事情

您期望的问题是完全不同的:您期望单元格左侧的句柄向上移动,保持在文本的中心,但句柄仍保持在整个单元格的中心,包括您添加的空边框

对于Java7和BasicLookAndFeel及其后代(如Windows和Metal),句柄线的垂直居中在实现中是硬编码的

因此,如果您希望句柄保持在文本的中心,唯一可行的解决方案是通过在顶部和底部添加相等的空白来保持文本的中心。

您可以尝试在渲染组件内部使用html,以便在没有
边框的情况下获得该效果。
设置行高()
,或
设置首选大小()
。这是您的渲染器:

class CustomCellRenderer extends DefaultTreeCellRenderer {

        @Override
        public Component getTreeCellRendererComponent(JTree tree,Object value, boolean isSelected, boolean expanded,boolean leaf, int row, boolean hasFocus) {
            JComponent c = (JComponent) super.getTreeCellRendererComponent(tree, value, isSelected, expanded, leaf, row, hasFocus);
            if (c instanceof JLabel) {
                ((JLabel) c).setText("<html><p style=\"padding-top: 8px;\">" + value + "<p/>");
            }
            return c;
        }

    }
class CustomCellRenderer扩展了DefaultTreeCellRenderer{
@凌驾
公共组件GetTreeCellRenderComponent(JTree树、对象值、布尔isSelected、布尔展开、布尔叶、int行、布尔hasFocus){
JComponent c=(JComponent)super.getTreeCellRenderComponent(树、值、isSelected、expanded、叶、行、hasFocus);
if(JLabel的c实例){
((JLabel)c).setText(“

“+value+”

”); } 返回c; } }


padding bottom
取而代之的是
padding top
以实现名称下的效果。

正如@Holger所提到的:水平线始终相对于节点高度居中,对此您无能为力。好奇你为什么想要它?