2011-04-28 55 views
2

我想在我的Swing应用程序的JTree,不具有叶节点的图标,所以我写了下面的代码:秋千JTree的图标呈现

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,将叶节点添加到正确的位置。在进行这些更改后调用repaint。包含的JScrollPane类被包装到一个JSplitPane中,该JSplitPane被渲染到框架中。

+0

这些很难跟踪没有看到代码 - BasicTreeUI做了大量的大小缓存,并不总是在适当时清除。再加上一些LAF默默地安装一个固定的rowHeight,这可以解决问题。 – kleopatra 2011-04-28 14:51:00

回答

1

这对我很好。仔细检查一下没有其他事情了。

如果您在树显示后更改此设置,请确保您正在重新绘制树。

一个丑陋的工作可能是100%透明的图标,而不是null。

+0

所有这些配置的东西都在树显示之前完成。我想这可能是我使用的L&F的问题。 – Oliver 2011-04-28 14:36:15

+0

此外,建立在[EDT](http://download.oracle.com/javase/tutorial/uiswing/concurrency/initial.html)上; JTree对此特别敏感。 – trashgod 2011-04-28 17:10:20

1

另一种方法是使用没有像素的实现,如建议here