2016-07-14 2 views
2

JTree의 DefaultMutableTreeNodes가 있으며이를 필터링하려고합니다.필터 jtree - 조건과 일치하는 노드의 모든 노드와 하위 노드 유지

필자는 필터를 수행 할 때 기준에 맞는 노드 또는 내 기준과 일치하는 하위 노드를 유지하려고합니다.

여기에는 참조 용 코드가 포함되어 있습니다.

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Component; 
import java.awt.EventQueue; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.Insets; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.Enumeration; 

import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTextField; 
import javax.swing.JTree; 
import javax.swing.border.EmptyBorder; 
import javax.swing.tree.DefaultMutableTreeNode; 
import javax.swing.tree.DefaultTreeCellRenderer; 
import javax.swing.tree.TreeModel; 

public class FilteredJTreeExample extends JFrame { 

    private static final long serialVersionUID = 1L; 
    private JPanel contentPane; 
    private JTextField textField; 
    private JTree tree; 

    /** 
    * Launch the application. 
    */ 
    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       try { 
        FilteredJTreeExample frame = new FilteredJTreeExample(); 
        frame.setVisible(true); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    /** 
    * Create the frame. 
    */ 
    public FilteredJTreeExample() { 
     //setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setBounds(100, 100, 450, 300); 
     contentPane = new JPanel(); 
     contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 
     contentPane.setLayout(new BorderLayout(0, 0)); 
     setContentPane(contentPane); 

     JPanel panel = new JPanel(); 
     contentPane.add(panel, BorderLayout.NORTH); 
     GridBagLayout gbl_panel = new GridBagLayout(); 
     gbl_panel.columnWidths = new int[]{34, 116, 0}; 
     gbl_panel.rowHeights = new int[]{22, 0}; 
     gbl_panel.columnWeights = new double[]{0.0, 1.0, Double.MIN_VALUE}; 
     gbl_panel.rowWeights = new double[]{0.0, Double.MIN_VALUE}; 
     panel.setLayout(gbl_panel); 

     JLabel lblFilter = new JLabel("Search:"); 
     GridBagConstraints gbc_lblFilter = new GridBagConstraints(); 
     gbc_lblFilter.anchor = GridBagConstraints.WEST; 
     gbc_lblFilter.insets = new Insets(0, 0, 0, 5); 
     gbc_lblFilter.gridx = 0; 
     gbc_lblFilter.gridy = 0; 
     panel.add(lblFilter, gbc_lblFilter); 

     JScrollPane scrollPane = new JScrollPane(); 
     contentPane.add(scrollPane, BorderLayout.CENTER); 

     tree = new JTree(); 
     tree.setEditable(true); 
     tree.setShowsRootHandles(false); 
     tree.setInvokesStopCellEditing(true); 
     scrollPane.setViewportView(tree); 

     textField = new JTextField(); 
     GridBagConstraints gbc_textField = new GridBagConstraints(); 
     gbc_textField.fill = GridBagConstraints.HORIZONTAL; 
     gbc_textField.anchor = GridBagConstraints.NORTH; 
     gbc_textField.gridx = 1; 
     gbc_textField.gridy = 0; 
     panel.add(textField, gbc_textField); 
     textField.setColumns(10); 
     textField.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent evt) { 
       TreeModel model = tree.getModel(); 
       tree.setModel(null); 
       tree.setModel(model); 
      } 
     }); 

     tree.setCellRenderer(new DefaultTreeCellRenderer() { 
      private JLabel lblNull = new JLabel(); 

      @Override 
      public Component getTreeCellRendererComponent(JTree tree, Object value, 
        boolean arg2, boolean arg3, boolean arg4, int arg5, boolean arg6) { 

       Component c = super.getTreeCellRendererComponent(tree, value, arg2, arg3, arg4, arg5, arg6); 

       DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; 
       if (matchesFilter(node)) { 
        c.setForeground(Color.BLACK); 
        return c; 
       } 
       else if (containsMatchingChild(node)) { 
        c.setForeground(Color.GRAY); 
        return c; 
       } 
       else { 
        return lblNull; 
       } 
      } 

      private boolean matchesFilter(DefaultMutableTreeNode node) { 
       return node.toString().contains(textField.getText()); 
      } 

      private boolean containsMatchingChild(DefaultMutableTreeNode node) { 
       Enumeration<DefaultMutableTreeNode> e = node.breadthFirstEnumeration(); 
       boolean isMatched = false; 
       while (e.hasMoreElements()) { 
        DefaultMutableTreeNode nextElement = e.nextElement(); 
        if (matchesFilter(nextElement)) { 
         isMatched = true; 
        } 
       } 
       return isMatched; 
      } 
     }); 
    } 
} 

출력 :

나는 "컬러"로 검색 텍스트를 입력하고 Enter를 클릭

enter image description here

. JTree 및 Colors 노드 만 표시됩니다.

문제 :

  1. 나는 색상의 아이를 보여주고 싶어요. 즉, 파란색, 보라색 등

  2. 내가 발견 한 또 다른 문제는 검색 작업을 수행 한 후 마우스 스크롤이 작동하지 않는 반면 정상적으로 작동하는 것입니다. "e"를 검색하여 프레임을 축소하고 마우스를 위 아래로 스크롤하여 재현 할 수 있습니다.

: 나는 우분투를 14.04 LTS를 사용하고 있습니다.

아이디어가 있으십니까?

+0

1.에 대해서는'int r = 0; while (r Marco13

+0

@ Marco13 : 이미 여기에 나와 있지 않은 모든 행동을 확장했다. 내 문제는, 일치하는 기준 인 부모의 자녀와 일치 할 수 없다는 것입니다. 여기에 JTree> Colors> 파란색 보라색 빨간색 노란색을 표시하고 싶습니다. – Tamil

+0

@ Marco13 : Issue-2에 관해서 : "e"(Enter 버튼을 누르십시오)를 입력하고 표시된 3 개의 레코드까지 프레임을 축소하고 다른 3 개의 레코드를 볼 수있는 스크롤을 내립니다. 그러나 스크롤을하면 이전 레코드가 표시되지 않습니다. 이것은 마우스 스크롤 (왼쪽 클릭 버튼 옆)에서 발생합니다. 스크롤을 오른쪽으로 끌면 작동합니다. – Tamil

답변

2

부모 중 하나 인 (조상)에 원하는 문자열이 포함 된 경우 노드가 포함 된 방법이 필요합니다. 예를 들어,

private boolean containsMatchingParent(DefaultMutableTreeNode node) 
{ 
    DefaultMutableTreeNode current = node; 
    while (current != null) 
    { 
     if (matchesFilter(current)) 
     { 
      return true; 
     } 
     current = (DefaultMutableTreeNode) current.getParent(); 
    } 
    return false; 
} 

(containsMatchingChild과 같은 방식으로 사용).

2

로 변경 matchesFilter() : 당신이 colors 노드를 확장 할 수 있도록 색상을 반환합니다

private boolean matchesFilter(DefaultMutableTreeNode node) 
{ 
    TreeNode parent = node; 
    while (parent != null) 
    { 
     if (parent.toString().contains(textField.getText())) 
     { 
      return true; 
     } 
     parent = parent.getParent(); 

    } 

    return false; 
} 

.

관련 문제