2

私はJTreeとを持っていJTextFieldます。ツリーでノードを選択すると、テキスト フィールドにノードの値が表示されます。次に、テキストを編集して保存し、選択したノードの値を変更します。DefaultTreeModelのメソッドを使用しnodeChangedてツリーを更新します。

これは、ツリー モデルにそのノードを更新するように指示する適切な方法ですか? ツリーのモデルに明示的にアクセスして、何かが起こったことを伝えているので、私には見苦しく見えます。

ここにいくつかのコードがあります

import java.awt.BorderLayout;
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.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.ScrollPaneConstants;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

public class TextPaneTest extends JFrame {

    private JTextField textBox = null;
    private JTree tree = null;
    private JButton button = null;

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

    public TextPaneTest() {

        // Main panel
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());

        // Panel holding tree
        JPanel treePanel = new JPanel();
        treePanel.setLayout(new BorderLayout());

        // Panel holding text field and button

        JPanel editPanel = new JPanel();
        editPanel.setLayout(new BorderLayout());

        // My textbox
        textBox = new JTextField();

        // button
        button = new JButton();
        button.setText("Save changes");
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e)
            {
                DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
                String text = textBox.getText();
                node.setUserObject(text);
                DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
                model.nodeChanged(node);
            }
        });

        // My Tree
        DefaultMutableTreeNode top = new DefaultMutableTreeNode("Root");
        tree = new JTree(top);
        tree.addTreeSelectionListener(new TreeSelectionListener() {
            public void valueChanged(javax.swing.event.TreeSelectionEvent evt) {
                DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
                textBox.setText(node.getUserObject().toString());
        }
        });

        JScrollPane scrollPane = new JScrollPane(tree);
        scrollPane.setHorizontalScrollBarPolicy(
            ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);

        // Add tree
        treePanel.add(scrollPane);
        panel.add(treePanel, BorderLayout.CENTER);

        // Add box and button to edit panel
        editPanel.add(textBox, BorderLayout.CENTER);
        editPanel.add(button, BorderLayout.SOUTH);

        // Add edit panel
        panel.add(editPanel, BorderLayout.SOUTH);

        // Add everything to the frame
        this.add(panel);
        this.setSize(300, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }
}
4

3 に答える 3

2

あなたの例は正しいようです。@matt の正解を拡張するとこの MVCのは洞察を提供する可能性があります。JTreeビューは編集もできるため、モデルのメソッドを呼び出すことができます。fireTreeNodesChanged()モデルは、ユーザーに代わって呼び出すことにより、ツリー自体を含むすべてのリスナーに通知します。効果を確認するには、別のリスナーを追加します。

tree.getModel().addTreeModelListener(new TreeModelListener() {
    @Override
    public void treeNodesChanged(TreeModelEvent e) {
        update(e);
    }

    @Override
    public void treeNodesInserted(TreeModelEvent e) {
        update(e);
    }

    @Override
    public void treeNodesRemoved(TreeModelEvent e) {
        update(e);
    }

    @Override
    public void treeStructureChanged(TreeModelEvent e) {
        update(e);
    }

    private void update(TreeModelEvent e) {
        System.out.println(e);
    }
});

その他の注意事項:

于 2013-10-17T20:40:56.287 に答える
1

DefaultTreeModel と DefaultMutableTreeNode の JavaDoc とコードを調べてみると、あなたがしていることは問題ないと思います。モデルの構造を変更した場合 (ノードを削除するなど)、モデルに対して何かを行ったことを TreeModel が認識しているため、モデルで何も呼び出す必要はありません。ただし、この場合、モデルが参照するノードの内容を変更しています。そのため、TreeModel の 1 つのノードの内容が異なることを TreeModel に通知する必要があるのは理にかなっているように思われます。

私自身が何か足りないかもしれませんが、あなたが持っているものは大丈夫だと思います。

于 2013-10-17T16:49:04.350 に答える