2017-12-24 17 views
0

私は、docs.oracle.comチュートリアルのDynamicTreeとDynamicTreeDemoクラスを使用しています。この例では、選択されたノードに子ノードを動的に追加することができます。手動で特定の行のJTreeにノードを挿入する

私がするTreePathを変更するための

DefaultMutableTreeNode addObject(Object child) 

機能を変更しました。それは私が追加ボタンをクリックするたびにそのパスにのみ子ノードを追加するように私は、ツリーパスを修正しました。

Object[] o = { new DefaultMutableTreeNode("Root Node"), new DefaultMutableTreeNode("Parent 2"), 
      new DefaultMutableTreeNode("Child 2") }; 

    parentPath = new TreePath(o); 

私の変更後、追加ボタンは機能しません。どのように私はコードのパスを変更してノードを追加できるように私はこの問題を解決することができますか?

import java.awt.GridLayout; 
import java.awt.Toolkit; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTree; 
import javax.swing.tree.DefaultMutableTreeNode; 
import javax.swing.tree.DefaultTreeModel; 
import javax.swing.tree.MutableTreeNode; 
import javax.swing.tree.TreePath; 
import javax.swing.tree.TreeSelectionModel; 
import javax.swing.event.TreeModelEvent; 
import javax.swing.event.TreeModelListener; 

public class DynamicTree extends JPanel { 
protected DefaultMutableTreeNode rootNode; 
protected DefaultTreeModel treeModel; 
protected JTree tree; 
private Toolkit toolkit = Toolkit.getDefaultToolkit(); 

public DynamicTree() { 
    super(new GridLayout(1, 0)); 

    rootNode = new DefaultMutableTreeNode("Root Node"); 
    treeModel = new DefaultTreeModel(rootNode); 
    treeModel.addTreeModelListener(new MyTreeModelListener()); 
    tree = new JTree(treeModel); 
    tree.setEditable(true); 
    tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); 
    tree.setShowsRootHandles(true); 

    JScrollPane scrollPane = new JScrollPane(tree); 
    add(scrollPane); 
} 

/** Remove all nodes except the root node. */ 
public void clear() { 
    rootNode.removeAllChildren(); 
    treeModel.reload(); 
} 

/** Remove the currently selected node. */ 
public void removeCurrentNode() { 
    TreePath currentSelection = tree.getSelectionPath(); 
    if (currentSelection != null) { 
     DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode) (currentSelection.getLastPathComponent()); 
     MutableTreeNode parent = (MutableTreeNode) (currentNode.getParent()); 
     if (parent != null) { 
      treeModel.removeNodeFromParent(currentNode); 
      return; 
     } 
    } 

    // Either there was no selection, or the root was selected. 
    toolkit.beep(); 
} 

/** Add child to the currently selected node. */ 
public DefaultMutableTreeNode addObject(Object child) { 
    DefaultMutableTreeNode parentNode = null; 
    TreePath parentPath = tree.getSelectionPath(); 

    //////////////////////////// Modification for fixing place /////////////  

    Object[] o = { new DefaultMutableTreeNode("Root Node"), new DefaultMutableTreeNode("Parent 2"), 
      new DefaultMutableTreeNode("Child 2") }; 

    parentPath = new TreePath(o); 

    //////////////////////////// end of modification/////////////////////// 


    if (parentPath == null) { 
     parentNode = rootNode; 
    } else { 
     parentNode = (DefaultMutableTreeNode) (parentPath.getLastPathComponent()); 
    } 

    return addObject(parentNode, child, true); 
} 

public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent, Object child) { 
    return addObject(parent, child, false); 
} 

public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent, Object child, boolean shouldBeVisible) { 
    DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(child); 

    if (parent == null) { 
     parent = rootNode; 
    } 

    // It is key to invoke this on the TreeModel, and NOT DefaultMutableTreeNode 
    treeModel.insertNodeInto(childNode, parent, parent.getChildCount()); 

    // Make sure the user can see the lovely new node. 
    if (shouldBeVisible) { 
     tree.scrollPathToVisible(new TreePath(childNode.getPath())); 
    } 
    return childNode; 
} 

class MyTreeModelListener implements TreeModelListener { 
    public void treeNodesChanged(TreeModelEvent e) { 
     DefaultMutableTreeNode node; 
     node = (DefaultMutableTreeNode) (e.getTreePath().getLastPathComponent()); 

     /* 
     * If the event lists children, then the changed node is the child of the node 
     * we've already gotten. Otherwise, the changed node and the specified node are 
     * the same. 
     */ 

     int index = e.getChildIndices()[0]; 
     node = (DefaultMutableTreeNode) (node.getChildAt(index)); 

     System.out.println("The user has finished editing the node."); 
     System.out.println("New value: " + node.getUserObject()); 
    } 

    public void treeNodesInserted(TreeModelEvent e) { 
    } 

    public void treeNodesRemoved(TreeModelEvent e) { 
    } 

    public void treeStructureChanged(TreeModelEvent e) { 
    } 
} 
} 





import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.tree.DefaultMutableTreeNode; 

public class DynamicTreeDemo extends JPanel implements ActionListener { 
private int newNodeSuffix = 1; 
private static String ADD_COMMAND = "add"; 
private static String REMOVE_COMMAND = "remove"; 
private static String CLEAR_COMMAND = "clear"; 

private DynamicTree treePanel; 

public DynamicTreeDemo() { 
    super(new BorderLayout()); 

    // Create the components. 
    treePanel = new DynamicTree(); 
    populateTree(treePanel); 

    JButton addButton = new JButton("Add"); 
    addButton.setActionCommand(ADD_COMMAND); 
    addButton.addActionListener(this); 

    JButton removeButton = new JButton("Remove"); 
    removeButton.setActionCommand(REMOVE_COMMAND); 
    removeButton.addActionListener(this); 

    JButton clearButton = new JButton("Clear"); 
    clearButton.setActionCommand(CLEAR_COMMAND); 
    clearButton.addActionListener(this); 

    // Lay everything out. 
    treePanel.setPreferredSize(new Dimension(300, 150)); 
    add(treePanel, BorderLayout.CENTER); 

    JPanel panel = new JPanel(new GridLayout(0, 3)); 
    panel.add(addButton); 
    panel.add(removeButton); 
    panel.add(clearButton); 
    add(panel, BorderLayout.SOUTH); 
} 

public void populateTree(DynamicTree treePanel) { 
    String p1Name = new String("Parent 1"); 
    String p2Name = new String("Parent 2"); 
    String c1Name = new String("Child 1"); 
    String c2Name = new String("Child 2"); 

    DefaultMutableTreeNode p1, p2; 

    p1 = treePanel.addObject(null, p1Name); 
    p2 = treePanel.addObject(null, p2Name); 

    treePanel.addObject(p1, c1Name); 
    treePanel.addObject(p1, c2Name); 

    treePanel.addObject(p2, c1Name); 
    treePanel.addObject(p2, c2Name); 
} 

public void actionPerformed(ActionEvent e) { 
    String command = e.getActionCommand(); 

    if (ADD_COMMAND.equals(command)) { 
     // Add button clicked 
     treePanel.addObject("New Node " + newNodeSuffix++); 
    } else if (REMOVE_COMMAND.equals(command)) { 
     // Remove button clicked 
     treePanel.removeCurrentNode(); 
    } else if (CLEAR_COMMAND.equals(command)) { 
     // Clear button clicked. 
     treePanel.clear(); 
    } 
} 

/** 
* Create the GUI and show it. For thread safety, this method should be invoked 
* from the event-dispatching thread. 
*/ 
private static void createAndShowGUI() { 
    // Create and set up the window. 
    JFrame frame = new JFrame("DynamicTreeDemo"); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    // Create and set up the content pane. 
    DynamicTreeDemo newContentPane = new DynamicTreeDemo(); 
    newContentPane.setOpaque(true); // content panes must be opaque 
    frame.setContentPane(newContentPane); 

    // Display the window. 
    frame.pack(); 
    frame.setVisible(true); 
} 

public static void main(String[] args) { 
    // Schedule a job for the event-dispatching thread: 
    // creating and showing this application's GUI. 
    javax.swing.SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGUI(); 
     } 
    }); 
} 
} 

答えて

0

あなたが作っ変更があるため、既存のものと同じ名前を持ついくつかの新しいDefaultMutableTreeNode Sを作成することによって、正しくない新しいTreePathが同じTreePath対象ではないノード。彼らの参照は同じではありません。次に、作成しているこの新しいパスはTreeModelにありません。結果は何も起こりません。

TreeModelから新しいノードを挿入するパスを取得する必要があります。あなたが特定の場所に新しいノードを追加したい場合は、あなたがへの参照を取得する必要があります

// ////////////////////////// Modification for fixing place // ///////////// 

Object[] o = { rootNode.getLastLeaf() }; // For you testing purposes 
             // this will return the Child 2" reference, 
             // next time it will return "New Node 2" and so on. 

parentPath = new TreePath(o); 

// ////////////////////////// end of modification/////////////////////// 

:あなたは子供2に新しい子を追加したい場合たとえば、あなたはこのようにその参照を取得することができますTreeModelの既存のノードTreeNodeは現在、TreeModelには存在しません。

これが役に立ちます。

+0

お返事ありがとうございます。私は前にこの方法を試してみました。しかし、私は私のコードで記述する特定のパスにノードを挿入したい。例えば、私は上記のコード "Root Node/Paren 2/Child 2"に書きました。このパスはクリックごとに異なります。私はここで "tree.getSelectionPath()"を使用するのではなく、treepathを変更するために立ち往生しています。私はどのようにこれを行うことができますか分かりません。 –

+0

私はツリーに新しいノードを追加するあなたのロジックを知らないが、重要な注意点は、メモリ内に新しい 'TreeNode'参照を作成するのではなく、' TreeModel'自体からそのパスを見つけることです。同じ名前の 'new DefaultMutableTreeNode'を作成する前に、既存のノードへの参照をtreeModelにしません。ツリーに新しいノードを追加するカスタムロジックがある場合は、 'rootNode'または' selectedNode'から始まるtreeModelを何とか探して、その特定のノードを新しいノードの親として見つけるべきです。 – STaefi

関連する問題