2011-02-17 1 views
3

시도 : F2 시작 편집 및 입력 편집을 중지하고 포커스를 다음 구성 요소로 전환하고 밀리 초 단위로 트리 노드로 돌아갑니다. 이 예에서는 JTabbedPane-Header에서 깜박이는 focusPainted 사각형을 볼 수 있습니다. FocusListener를 사용하면 명확 해집니다.노드를 편집 한 후 JTree에서 짧은 시간 동안 포커스를 잃는 이유는 무엇입니까?

노드 편집 후 JTree에서 짧은 시간 동안 포커스를 잃는 이유는 무엇입니까?

이 동작을 방지하려면 어떻게해야합니까?

public class Focus { 

private static void createAndShowGUI() { 
    final JTextArea text = new JTextArea("Tab Header gained focus"); 

    JTree tree = new JTree(); 
    tree.setEditable(true); 
    int row = 0; 
    while(row < tree.getRowCount()) { 
     tree.expandRow(row++); 
    } 

    JTabbedPane tabp = new JTabbedPane(); 
    tabp.addTab("Lorem", text); 
    tabp.addFocusListener(new FocusListener() { 
     @Override 
     public void focusLost(FocusEvent e) { } 
     @Override 
     public void focusGained(FocusEvent e) { 
      text.setText(text.getText() +"\nWoohoo, I got the focus!"); 
     } 
    }); 

    JFrame frame = new JFrame("Focus"); 
    frame.setLayout(new BorderLayout()); 
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
    frame.getContentPane().add(tree, BorderLayout.WEST); 
    frame.getContentPane().add(tabp, BorderLayout.CENTER); 
    frame.pack(); 
    frame.setLocationRelativeTo(null); 
    frame.setVisible(true); 

    tree.startEditingAtPath(tree.getPathForRow(0)); 

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

트리 노드 편집을 마친 후 Enter 키를 누르면 포커스는 방금 편집 한 JTree 노드에 유지됩니다. F2를 다시 누르면 마우스를 어디로 이동하든 동일한 노드를 다시 편집 할 수 있습니다. 초점은 괜찮아 보인다. –

답변

2

트리는 편집을 시작할 때 JTree 계층 구조에 DefaultCellEditor를 추가합니다. 이 텍스트 필드에 중점을 둡니다. 편집을 중단하면 (Enter 키 누름) BasicTreeUI.completeEditing() 메서드는 트리 자체 또는 편집기 구성 요소가 포커스 소유자인지 여부를 확인합니다. 이 경우 트리는 편집이 끝나면 다시 초점을 맞 춥니 다.

정지 알고리즘에서 편집기가 트리에서 제거됩니다. 이전에는 포커스 소유자 였으므로 포커스는 다음 포커스 가능 구성 요소로 이동됩니다 (포커스 사이클). 귀하의 UI에서 이것은 탭 패널이 될 것입니다.

편집자가 전에 집중했기 때문에 BasicTreeUI는 트리에 대한 포커스를 요청합니다.

이 단계는 설명 된 동작에 완벽하게 매핑됩니다.

유일한 해결책 (완료되지 있지만, 방향 표시)는 자신의 FocusTraversalPolicy를 설정하는 것입니다 :

private static class TreeEditorFocusTraversalPolicy extends DefaultFocusTraversalPolicy { 
    private final JTree tree; 
    public TreeEditorFocusTraversalPolicy(JTree tree) { 
     this.tree = tree; 
    } 

    @Override 
    public Component getComponentAfter(Container aContainer, Component aComponent) { 
     if (aComponent instanceof CellEditor) { 
      return tree; 
     } 
     return super.getComponentAfter(aContainer, aComponent); 
    } 
} 

설정하여 트리에이 인스턴스 :

tree.setFocusTraversalPolicy(new TreeEditorFocusTraversalPolicy(tree)); 
tree.setFocusCycleRoot(true); 

문제까지 다음 포커스 이동 (Tab, Shift + Tab)이 더 이상 작동하지 않습니다. FocusTraversalPolicy는 Swing의 많은 부분을 차지하고 있으며, 작동하는 정책을 수립하는데 약간의 시간이 필요합니다. 어쩌면 기본 정책 인 LegacyGlueFocusTraversalPolicy를 살펴보십시오.

희망이 있으면 도움이 될 것입니다.