Swing JTree рендеринг иконок - PullRequest
       25

Swing JTree рендеринг иконок

2 голосов
/ 28 апреля 2011

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

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

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

Badly rendered tree

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

enter image description here

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

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, который добавляет в конечные узлы нужные места. перекрас вызывается после внесения этих изменений. Содержащий класс JScrollPane оборачивается в JSplitPane, который отображается в кадре.

Ответы [ 2 ]

1 голос
/ 28 апреля 2011

Альтернативой является использование реализации без пикселей, как предлагается здесь .

1 голос
/ 28 апреля 2011

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

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

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

...