2013-10-11 2 views
2

트리의 일부 노드에 아이콘이있는 JTree가 있습니다. 아이콘이있는 노드를 선택하면 렌더러가 전체 노드를 선택하지는 않지만 아이콘이 아래 노드의 왼쪽에 있다고 생각하는 것처럼 오프셋이 적용된 것처럼 보입니다. :JTree 셀 렌더러 문제

Example of the rendering fault

(DefaultTreeCellRenderer 확장) 렌더러에 대한 코드는 다음과 같습니다 :

public ProfileTreeRenderer() { 
    super.setLeafIcon(null); 
    super.setClosedIcon(null); 
    super.setOpenIcon(null); 
} 

@Override 
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { 
    Component c = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); 
    if (c instanceof JLabel) { 
     JLabel label = (JLabel) c; 
     label.setHorizontalTextPosition(SwingConstants.LEADING); 
    } 

    if(sel && !hasFocus) { 
     setBackgroundSelectionColor(UIManager.getColor("Panel.background")); 
     setTextSelectionColor(UIManager.getColor("Panel.foreground")); 
    } else { 
     setTextSelectionColor(UIManager.getColor("Tree.selectionForeground")); 
     setBackgroundSelectionColor(UIManager.getColor("Tree.selectionBackground")); 
    } 

    if (value instanceof ProfileNode) { 
     ProfileNode node = (ProfileNode) value; 
     if (node.isUsed() && !sel) { 
      c.setForeground(Color.GRAY); 
     } 

     if (node.getIcon() != null) { 
      setIcon(node.getIcon()); 
     } 
    } 
} 
내가 렌더러이 오프셋 적용됩니다, 그래서 사람이 얻을 수있는 방법을 제공 할 수있는 이유를 볼 수 없습니다

노드가 아이콘으로 완전히 선택 되었습니까? 트리 자체에 대한 SSCCE 코드는 다음과 같습니다.

public class Example extends JDialog { 
    public Example() { 
     JTree tree = new JTree(createModel()); 
     tree.setCellRenderer(new ProfileTreeRenderer()); 

     setLayout(new BorderLayout()); 
     add(tree, BorderLayout.CENTER); 
    } 

    private TreeModel createModel() { 
     ProfileNode root = new ProfileNode("Profiles"); 

     ProfileNode userA = new ProfileNode("Example User A"); 
     ProfileNode userB = new ProfileNode("Example User B"); 

     // You'll need to subsitute your own 16x16 icons here 
     userA.setIcon(ImageSet.USER_ICON); 
     userB.setIcon(ImageSet.USER_ICON); 

     root.add(userA); 
     root.add(userB); 

     return new DefaultTreeModel(root); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new Example().setVisible(true); 
      } 
     }); 
    } 
} 

ProfileNode 클래스 : 사전에

public class ProfileNode extends DefaultMutableTreeNode { 

    @Getter private String labelDisplay; 
    @Getter @Setter private ImageIcon icon; 

    @Getter @Setter private boolean isUsed = false; 

    public ProfileNode(String labelDisplay) { 
     this.labelDisplay = labelDisplay; 
    } 

    @Override 
    public String toString() { 
     return labelDisplay; 
    } 
} 

감사합니다.

+1

: 당신은 다시 조정 ... 나 같은

뭔가 :-) SwingX 렌더러를 사용할 필요가? 어쨌든, 문제를 나타내는 SSCCE를 보여주십시오 :-) – kleopatra

+0

아니요, 문제는 JXTree (그에 따라 업데이트 된 질문)에 맞지 않습니다. SSCCE가 추가되었습니다. – Ocracoke

+0

코드가 "S"중 하나를 위반하고 있습니다 :-) 독립형으로 변경하십시오. – kleopatra

답변

2

문제는 DefaultTreeCellRenderer가 open/leaf/close 아이콘 전용 아이콘 속성을 사용한다는 것입니다. 즉, 아이콘! = null 인 경우 구성 요소의 시작 부분에 있다고 가정합니다. 그에 따라 선택을 조정합니다. (일반 JTree에 대) JXTree이 특정

JXTree tree = new JXTree(); 
tree.expandAll(); 
IconValue iv = new IconValue() { 

    Icon icon = XTestUtils.loadDefaultIcon("green-orb.png"); 
    @Override 
    public Icon getIcon(Object value) { 
     return value.toString().contains("s") ? icon : null; 
    } 

}; 
StringValue converter = new MappedValue(StringValues.TO_STRING, iv); 
WrappingProvider provider = new WrappingProvider(IconValues.NONE, converter); 
// hacking around missing api ... 
LabelProvider wrappee = (LabelProvider) provider.getWrappee(); 
wrappee.getRendererComponent(null).setHorizontalTextPosition(JLabel.LEADING); 
TreeCellRenderer r = new DefaultTreeRenderer(provider); 
tree.setCellRenderer(r); 
+0

예제 나 실제 코드에서이 대답을 만들 수 없습니다. 그러나 DefaultTreeCellRenderer에서이 비헤이비어의 이유를 찾아 내고 내가 가지고 있었던 문제를 해결하기 위해보다 일반적인 렌더러를 개발했습니다. 나는이 대답을 받아 들일 것이다. 조금 더 많은 일을하면, 내 코드에서 작동하게 만들 수 있다고 상상할 수있다. – Ocracoke

+0

흠 ... 그대로 작동해야합니다 (정확하게 기억하는 경우 SwingX를 사용하고 있습니까?) – kleopatra

+0

그래, 여전히 벗어나지 않았습니다. SwingX의 이전 버전을 사용하고있을 수도 있지만 그럴 수 있을지는 의문입니다. 아이콘이없고 트리의 노드의 toString을 사용하지 않으면 올바르게 작동하지 않습니다. – Ocracoke

관련 문제