Рендеринг значков Swing JTree

Я хочу, чтобы JTree в моем приложении Swing не имел значка для листовых узлов, поэтому я написал следующий код:

    DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer)
        jtree.getCellRenderer();
    renderer.setLeafIcon(null);
    jtree.setCellRenderer(renderer);

Это правильно удаляет значки для листьев, но также приводит к следующей ошибке рендеринга:

Плохо отрисованное дерево

Вы можете видеть, что метки, прикрепленные к узлам ветвления, усечены и расположены слишком близко друг к другу. Если я разверну, а затем сверну все узлы ветвей, проблема устранится сама собой:

введите здесь описание изображения

Если я закомментирую строку:

renderer.setLeafIcon(null);

Проблема исчезает (но значок листа, который мне не нужен, присутствует.)

Любые идеи, как это исправить?

Изменить: я добавлю весь соответствующий код.

public class StepChooserPanel extends JScrollPane { 
private JTree rules;

public StepChooserPanel(TabPanel parent){
    super();

    this.setBackground(Color.white);


    DefaultMutableTreeNode top = new DefaultMutableTreeNode("top");
    rules = new JTree();
    rules.getSelectionModel()
        .setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
    rules.setRootVisible(false);
    rules.setScrollsOnExpand(false);
    rules.setToggleClickCount(1);
    rules.addTreeSelectionListener(parent);
    rules.putClientProperty("JTree.lineStyle", "None");


    DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer)
        rules.getCellRenderer();
    renderer.setLeafIcon(null);
    rules.setCellRenderer(renderer);

    this.setViewportView(rules);

}

public void populateFilterRules(InferenceSystem system){

    DefaultMutableTreeNode root = new DefaultMutableTreeNode();
    TreeModel treeModel = new DefaultTreeModel(root);
    rules.setModel(treeModel);

    List<Rule> systemRules = system.getSortedRules();       
    for(int i = 0; i < systemRules.size(); i++){
        if(!(systemRules.get(i) instanceof InferenceRule)){
            continue;
        }
        DefaultMutableTreeNode rule = new DefaultMutableTreeNode
                (systemRules.get(i).getName());
        root.add(rule);
    }

    rules.expandPath(new TreePath(root.getPath())); 

    this.repaint();     
}

public void populateRewriteList(Collection<Rewrite> choices){

    DefaultMutableTreeNode root = (DefaultMutableTreeNode) rules.getModel()
        .getRoot();

    for(Rewrite rr : choices){
        for (int i = 0; i < root.getChildCount(); i++){
            String ruleName = (String) ((DefaultMutableTreeNode)root.getChildAt(i))
                                    .getUserObject();
            if(rr.getRule().getName().equals(ruleName)){
                ((DefaultMutableTreeNode)root.getChildAt(i))
                    .add(new DefaultMutableTreeNode(rr));
            }
        }           
    }   

    this.repaint();
}

Вся настройка производится в конструкторе. Вызывается populateFilterRules, который добавляет узлы ветки. Затем вызывается populateRewriteList, который добавляет листовые узлы в нужные места. repaint вызывается после внесения этих изменений. Содержащий класс JScrollPane упаковывается в JSplitPane, который визуализируется во фрейме.


person Oliver    schedule 28.04.2011    source источник
comment
их трудно отследить, не видя кода - BasicTreeUI выполняет большое кэширование размера, которое не всегда очищается, когда это необходимо. Кроме того, некоторые LAF молча устанавливают фиксированную высоту строки, что усугубляет проблему.   -  person kleopatra    schedule 28.04.2011


Ответы (2)


Это отлично работает для меня. Дважды проверьте, не происходит ли что-то еще.

Если вы меняете это после отображения дерева, убедитесь, что вы перерисовываете дерево.

Уродливым обходным решением может быть 100% прозрачный значок вместо нуля.

person jzd    schedule 28.04.2011
comment
Все эти настройки выполняются до отображения дерева. Я предполагаю, что это может быть проблема с L&F, который я использую. - person Oliver; 28.04.2011
comment
Кроме того, используйте EDT; JTree особенно чувствителен к этому. - person trashgod; 28.04.2011

Альтернативой является использование реализации без пикселей, как это предлагается каждый узел-из-jtree-in-java/5263600#5263600">здесь.

person trashgod    schedule 28.04.2011