2013-11-21 3 views
2

Я хочу, чтобы мой JTree имел переменную высоту строки. Из того, что я прочитал, все, что мне нужно сделать, это setRowHeight(0) и реализовать пользовательский TreeCellRenderer. Внутри TreeRenderer установлены разные границы, в зависимости от элемента. однако при добавлении границы высота строки остается неизменной. Например, когда добавляется EmptyBorder(0,0,8,0), метка перемещается вверх на 8 пикселей. Таким образом, вместо ожидаемого результата на левой стороне, дерево выглядит как на правом:JTree: переменная высота строки

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; 
    } 

} 
+0

как уже упоминалось @Holger: горизонтальная линия всегда центрирована относительно высоты узла, и вы ничего не можете с этим поделать. Любопытно, зачем вам это нужно? – kleopatra

ответ

2

Вы предположение неверно, высота строки не остался тоже самое. Высота строки - это расстояние между верхней и нижней частью строки, другими словами, занимаемое пространство между строками выше и ниже. На вашем эскизе четко видно увеличенное расстояние, и это действительно так.

Проблема с вашим ожиданием совершенно другая: вы ожидаете, что ручка слева от ячейки перемещается вверх, оставаясь в центре текста, но ручка остается в центре всей ячейки, включая пустую границу, которую вы добавили.

С точки зрения Java 7 и BasicLookAndFeel и его потомков (например, Windows и Metal) вертикальное центрирование линии рукояток жестко запрограммировано в реализации.

Поэтому, если вы хотите, чтобы ручка оставалась в центре текста, единственное практическое решение состоит в том, чтобы сохранить текст в центре, добавив пустое пространство равным верхнему и нижнему.

1

Вы можете попробовать использовать HTML внутри визуализируемый компонент для получения этого эффекта без Border или setRowHeight() или setPreferredSize(). Вот ваш рендер:

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; 
     } 

    } 

enter image description here

padding-bottom вместо padding-top для этого эффекта под названием.

Смежные вопросы