2013-06-05 7 views
2

JTree가 있고 여러 노드를 선택할 수 있습니다 (Ctrl 키). 마우스 오른쪽 버튼을 클릭하면 '새로 고침'을 선택할 수있는 팝업 창이 나타납니다. (이 방법에 대해 설명하는 다른 질문이 있습니다)jtree 마우스 오른쪽 버튼으로 하나의 노드 만 선택

여러 노드를 선택하고 마우스 오른쪽 버튼을 클릭하면 오른쪽 클릭 한 노드 만 선택되고 다른 노드는 선택 취소됩니다.

예를 들어 노드 3 개 (리프)를 선택하고 마우스 오른쪽 버튼을 클릭 한 다음 '새로 고침'을 선택하고 해당 노드 3 개를 계속 선택하려고합니다.

어떤 조언이 필요합니까? 감사!

예 :

import javax.swing.*; 
import javax.swing.tree.DefaultMutableTreeNode; 
import javax.swing.tree.TreePath; 
import javax.swing.tree.TreeSelectionModel; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 

public class JTreeMultiSelect extends JFrame{ 

    public JTreeMultiSelect() { 
     super("Test"); 

     JTree myTree = new JTree(); 
     myTree.getSelectionModel() 
       .setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION); 
     // add MouseListener to tree 
     MouseAdapter ma = new MouseAdapter() { 
      private void myPopupEvent(MouseEvent e) { 
       int x = e.getX(); 
       int y = e.getY(); 
       JTree tree = (JTree)e.getSource(); 
       TreePath path = tree.getPathForLocation(x, y); 
       if (path == null) 
        return; 

       tree.setSelectionPath(path); 

       DefaultMutableTreeNode rightClickedNode = 
         (DefaultMutableTreeNode)path.getLastPathComponent(); 

       if(rightClickedNode.isLeaf()){ 
        JPopupMenu popup = new JPopupMenu(); 
        final JMenuItem refreshMenuItem = new JMenuItem("refresh"); 
        refreshMenuItem.addActionListener(new ActionListener(){ 
         @Override 
         public void actionPerformed(ActionEvent actionEvent) { 
          System.out.println("refresh!"); 
         } 
        }); 
        popup.add(refreshMenuItem); 
        popup.show(tree, x, y); 
       } 
      } 
      public void mousePressed(MouseEvent e) { 
       if (e.isPopupTrigger()) myPopupEvent(e); 
      } 
      public void mouseReleased(MouseEvent e) { 
       if (e.isPopupTrigger()) myPopupEvent(e); 
      } 
     }; 

     myTree.addMouseListener(ma); 

     JPanel myPanel = new JPanel(); 
     myPanel.add(myTree); 
     this.add(myPanel); 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     this.pack(); 
     this.setVisible(true); 

    } 

    public static void main(String[] args) { 
     new JTreeMultiSelect(); 
    } 

} 
+0

더 나은 도움을 받으려면 TreeSelectionListener, 선택 모드, getSelectedXxx 코드 및 호출 방법을 추가하여 JFrame 및 JTree에 대해서만 짧고 실행 가능한 컴파일 가능한 [SSCCE] (http://sscce.org/) JPopupMenu를 볼 수 있습니다 – mKorbel

+0

코드를 보여주세요! 마우스 오른쪽 버튼으로 선택 항목을 변경하는 것처럼 들리지만 일부 코드가 표시되지 않으면 알 수 없습니다. – LiverpoolFTW

+0

코드를 추가했습니다. 그것은 트리에 있습니다 .setSelectionPath (경로); –

답변

2

tree.setSelectionPath(path); 

는 단일 항목에 트리 선택을 재설정 다음 줄.

if (tree.isSelectionEmpty()) { 
    tree.setSelectionPath(path); 
} 
+1

또는 마우스 오른쪽 클릭시 적어도 하나의 행을 선택하려면'tree.isSelectionEmpty()'가 true를 리턴 할 때만 해당 행을 실행할 수 있습니다. – VGR

+0

@VGR 좋은 생각. 대답에 추가했습니다. – Howard

+0

오른쪽 클릭의 위치를 ​​결정하고 해당 행의 선택 여부를 확인한 다음 선택을 변경하십시오. 선택한 행 외부에서 오른쪽 클릭이 발생하면 먼저 행을 선택하십시오. – Robin

2
여기

의견에 약속대로 작업 예제 :

import javax.swing.*; 
    import javax.swing.tree.DefaultMutableTreeNode; 
    import javax.swing.tree.TreePath; 
    import javax.swing.tree.TreeSelectionModel; 
    import java.awt.event.ActionEvent; 
    import java.awt.event.ActionListener; 
    import java.awt.event.MouseAdapter; 
    import java.awt.event.MouseEvent; 

    public class JTreeMultiSelect extends JFrame{ 

     public JTreeMultiSelect() { 
      super("Test"); 

      JTree myTree = new JTree(); 
      myTree.getSelectionModel() 
        .setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION); 
      // add MouseListener to tree 
      MouseAdapter ma = new MouseAdapter() { 
       private void myPopupEvent(MouseEvent e) { 
        int x = e.getX(); 
        int y = e.getY(); 
        JTree tree = (JTree)e.getSource(); 
        TreePath path = tree.getPathForLocation(x, y); 
        if (path == null) 
         return; 

        DefaultMutableTreeNode rightClickedNode = 
          (DefaultMutableTreeNode)path.getLastPathComponent(); 

        TreePath[] selectionPaths = tree.getSelectionPaths(); 

        //check if node was selected 
        boolean isSelected = false; 
        if (selectionPaths != null) { 
         for (TreePath selectionPath : selectionPaths) { 
          if (selectionPath.equals(path)) { 
           isSelected = true; 
          } 
         } 
        } 
        //if clicked node was not selected, select it 
        if(!isSelected){ 
         tree.setSelectionPath(path); 
        } 

        //todo : create custom JMenuItem that takes the selectionPaths as parameter 
        //  and do the action for each node (using getLastPathComponent) 
        if(rightClickedNode.isLeaf()){ 
         JPopupMenu popup = new JPopupMenu(); 
         final JMenuItem refreshMenuItem = new JMenuItem("refresh"); 
         refreshMenuItem.addActionListener(new ActionListener(){ 
          @Override 
          public void actionPerformed(ActionEvent actionEvent) { 
           System.out.println("refresh!"); 
          } 
         }); 
         popup.add(refreshMenuItem); 
         popup.show(tree, x, y); 
        } 
       } 
       public void mousePressed(MouseEvent e) { 
        if (e.isPopupTrigger()) myPopupEvent(e); 
       } 
       public void mouseReleased(MouseEvent e) { 
        if (e.isPopupTrigger()) myPopupEvent(e); 
       } 
      }; 

      myTree.addMouseListener(ma); 

      JPanel myPanel = new JPanel(); 
      myPanel.add(myTree); 
      this.add(myPanel); 
      this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      this.pack(); 
      this.setVisible(true); 

     } 

     public static void main(String[] args) { 
      new JTreeMultiSelect(); 
     } 

    } 
당신은 원하는 동작을 얻기 위해이 줄을 제거하거나 더 나은 또한 어떤 선택의 경우를 처리하는 조건 안에 넣어 할 수 있습니다