안에

2013-03-29 2 views
1

이 있고 JScrollPane 안에 JTree가 흐리게 표시됩니다. 스크롤 막대를 사용하면 아래 이미지에서 볼 수 있듯이 트리가 모두 흐려집니다.안에

창을 최소화 및 복원하거나 노드를 확장하거나 축소하려면 다시 그리기 위해 뭔가를하면 정상으로 돌아옵니다 (단, 노드를 드래그하면 흐려지지 않습니다. 창을 화면에서 떼어 내고 뒤로 또는 다른 창을 그 앞에서 드래그).

JTree에는 사용자 정의 TreeModel과 셀 렌더러가 있습니다. 최근 변경된 내용은 TreeModel입니다. 셀 렌더러는 오랫동안 거기에 있었고 잘 작동했습니다. 셀 렌더러는 DefaultTreeCellRenderer의 하위 클래스이며 사용자 정의 아이콘을 표시하기 위해 getTreeCellRendererComponent 메서드 만 재정의됩니다.

표시 할 데이터가 들어있는 데이터 구조에서 DefaultMutableTreeNodes를 채우는 데 사용되었지만 노드 수가 많으면 (10,000 이상) 성능 문제가 발생했습니다. 내가 가지고있는 데이터가 이미 트리 구조에 있었기 때문에 DefaultMutableTreeNode을 사용하지 않고도 사용자 정의 TreeModel을 만드는 것이 매우 간단하다는 것을 알았습니다. 이로 인해 JTree는 더 빨리 채워지지만 지금은 이처럼 흐린 스크롤 문제가 남아 있습니다.

Blurred JTree

아래 코드는 응용 프로그램에서가 아니라하고 문제를 시연 할 예정으로 컴파일. tree.setBackground 줄을 제거하면 흐릿한 동작이 중지됩니다.

package stackoverflow; 

import javax.swing.event.TreeModelListener; 
import javax.swing.tree.TreeModel; 
import javax.swing.tree.TreePath; 
import javax.swing.*; 
import java.awt.Color; 


public class NumberTreeModel implements TreeModel { 

    public static final int ROOT_NUMBER = 100; 

    public Object getChild(Object parent, int index) { 
     return index; 
    } 

    public int getChildCount(Object node) { 
     return isLeaf(node) ? 0 : ROOT_NUMBER; 
    } 

    @Override 
    public int getIndexOfChild(Object parent, Object child) { 
     int parentValue = ((Integer) parent).intValue(); 
     int childValue = ((Integer) child).intValue(); 
     return parentValue == ROOT_NUMBER ? childValue : -1 ; 
    } 

    public Object getRoot() { 
     return ROOT_NUMBER; 
    } 

    public boolean isLeaf(Object node) { 
     return ((Integer) node).intValue() < ROOT_NUMBER; 
    } 

    public void addTreeModelListener(TreeModelListener listener) { } 
    public void removeTreeModelListener(TreeModelListener listener) { } 
    public void valueForPathChanged(TreePath path, Object obj) { } 

    public static void display() { 

     JFrame frame = new JFrame("Number JTree"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     NumberTree tree = new NumberTree(); 
     tree.setModel(new NumberTreeModel()); 
     tree.setBackground(new Color(0,0,0,0)); 
     JScrollPane scroll = new JScrollPane(tree); 
     frame.add(scroll); 
     scroll.getViewport().setScrollMode(JViewport.BLIT_SCROLL_MODE); 
     tree.expandRow(0); 
     frame.pack(); 
     frame.setSize(300, 400); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static class NumberTree extends JTree { 
     static final long serialVersionUID = 1; 

     @Override 
     public String convertValueToText(Object value, boolean selected, boolean expanded, boolean leaf, 
       int row, boolean hasFocus) { 
     if (value instanceof Integer) { 
      int n = ((Integer) value).intValue(); 
      return n + "=========".substring(0, n % 10); 
     } else { 
      System.out.println("value class=" + value.getClass()); 
      return value.toString(); 
     } 
     } 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      display(); 
     } 
     }); 
    } 
} 
+0

포함하도록 질문을 수정하시기 바랍니다 [sscce] (http://sscce.org/) 당신이 설명하는 문제를 전시하고있다. – trashgod

+3

스윙의 투명성 요구 사항을 준수하지 않는 경우가 있습니다. 예. 배경색을 투명하거나 반투명 한 값으로 설정하려고 시도합니다. – MadProgrammer

+0

CustomCellRenderer와 JTree.convertValueToText의 재정의를 제거한 후에도 여전히 동일한 문제가 발생합니다. – Gigatron

답변

0

솔루션 :

  • 비 불투명 한 색으로 JTree의 배경을 변경할 수 setColor를 사용하지 마십시오. 노드의 시각적 투명성을 위해

  • JScrollPaneJViewport.SIMPLE_SCROLL_MODE의 뷰포트 모드를 설정 JTree set background of node to non-opaque

    • 에 설명 된 스크롤 흐림 문제를 도움으로, getBackgroundNonSelectionColorgetBackground에 null을 반환하는 사용자 정의 TreeCellRenderer을 구현하지만, 확장과 붕괴에 대한 문제를 다시 칠할 필요는 없습니다.
+0

명확한 설명을 위해 : a) 반투명 배경을 _any_ 구성 요소로 설정하려면 opacity 속성을 false로 설정해야합니다. 그렇지 않으면 페인팅 인공물이 발생합니다. 기술적으로는 (슈퍼 paintComponent에 호출하지 않고 재정의) 의심 @trashgod 동일한 오류 b)는 DefaultTreeCellRenderer [그 배경에 대하여 이상한 구현] 오히려을 갖는다이기 (http://stackoverflow.com/q/13735987/203657) – kleopatra

2

난 당신이 paintComponent()을 무시하지만 here을 같이 super.paintComponent(g) 소홀히 생각한다.

스크롤 창 뷰포트에서 setScrollMode()으로 실험 할 가능성이 낮습니다.

sscce을 포함하도록 질문을 편집하면 문제가 명확해질 수 있습니다.

부록 : 참고로, 여기에 이 아니고의 질문에 표시된 렌더링 아티팩트가있는 예가 있습니다.

enter image description here

import java.awt.EventQueue; 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTree; 

/** 
* @see https://stackoverflow.com/a/15696825/230513 
*/ 
public class Sscce { 

    private void display() { 
     JFrame f = new JFrame("Sscce"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     JTree tree = new JTree(); 
     for (int i = 0; i < tree.getRowCount(); i++) { 
      tree.expandRow(i); 
     } 
     f.add(new JScrollPane(tree)); 
     f.pack(); 
     f.setSize(200, 200); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new Sscce().display(); 
      } 
     }); 
    } 
} 
+0

어디서나'paintComponent'를 오버라이드하지 않았습니다. 'JTree.convertValueToText'를 오버라이드하여 toString()의 기본 기능 대신 각 노드에 적절한 문자열을 표시하고 질문에서 언급 한대로 'getTreeCellRendererComponent'를 무시합니다. – Gigatron

+0

뷰포트 스크롤 모드를 SIMPLE_SCROLL_MODE (으)로 변경하면 블러 링이 중단되었습니다 (다른 두 모드에는 여전히 흐림이 있음). 그러나 트리가 크면 트리가 채워질 때 GUI가 오랫동안 멈 춥니 다. 내 커스텀 TreeModel의'getIndexOfChild'에서 성능 향상이 필요하다고 생각합니다. 그래서 그것에 대해 작업하고 어떤 일이 일어나는지 살펴볼 것입니다. – Gigatron

+0

SIMPLE_SCROLL_MODE가 스크롤링 흐림 문제를 해결했지만 이제는 노드를 확장하거나 축소 할 때 때때로 제대로 새로 고쳐지지 않는 또 다른 문제가 있습니다. 그러나 나는 해결책을 찾고 있다고 생각한다. SSCCE를 포함하여 오늘 오후에 자세한 내용이 있습니다. – Gigatron