データモデルが更新されたことを通知する

広告

JTreeクラスのオブジェクトが作成され表示された後で、新しいノードが追加されたりノードが削除された時にデータモデルが更新されたことを通知する必要があります。DefaultTreeModelクラスで用意されている「reload」メソッドを使います。

public void reload()

ユーザーがこのモデルの依存する TreeNode を変更した場合、このメソッドを呼
び出します。モデルは、それ自身が変更済みであることを、そのリスナーのすべ
てに通知します。

このメソッドを呼び出すことでデータモデルに変更があったことが通知されます。このメソッドを呼び出さないとデータの追加や削除があったことが反映されません。

実際の使い方は次のようになります。

String[] treedata = {"Swing", "Java2D", "Java3D", "JavaMail"};
JTree tree = new JTree(treedata);

DefaultTreeModel model = (DefaultTreeModel)tree.getModel();

DefaultMutableTreeNode node = 
      (DefaultMutableTreeNode)tree.getLastSelectedPathComponent();

node.add(new DefaultMutableTreeNode("new node"));
model.reload();

データモデルの内容が変更されたことを通知する

データモデルの内容が変更された場合などデータの項目には増減がないけれど内容が変更されて表示されるべき内容が変更されたことを通知する場合はDefaultTreeModelクラスで用意されている「nodeChanged」メソッドを使います。

public void nodeChanged(TreeNode node)

ユーザーがツリー内のノードの表現方法を変更したあとで、このメソッドを呼
び出します。

引数には変更があったTreeNodeインターフェースを実装したクラスのオブジェクトを指定します。

なお「nodeChange」メソッドの代わりに「reload」メソッドを使ってもデータモデルの内容が変更されたことを通知されますが、「reload」メソッドを使った場合はJTreeが最初から再描画されるのに対して「nodeChage」メソッドを使った場合は該当ノードだけが再描画されます。

実際の使い方は次のようになります。

String[] treedata = {"Swing", "Java2D", "Java3D", "JavaMail"};
JTree tree = new JTree(treedata);

DefaultTreeModel model = (DefaultTreeModel)tree.getModel();

DefaultMutableTreeNode node = 
      (DefaultMutableTreeNode)tree.getLastSelectedPathComponent();

node.setUserObject(new DefaultMutableTreeNode("new name"));
model.nodeChange(node);

サンプルプログラム

では簡単なサンプルを作成して試してみます。

JTreeTest24.java

import javax.swing.*;
import java.awt.Dimension;
import java.awt.BorderLayout;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.DefaultMutableTreeNode;
import java.awt.event.*;

public class JTreeTest24 extends JFrame implements ActionListener{

  JTree tree;
  DefaultTreeModel model;
  JTextField text;

  public static void main(String[] args){
    JTreeTest24 frame = new JTreeTest24();

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setBounds(10, 10, 300, 250);
    frame.setTitle("タイトル");
    frame.setVisible(true);
  }

  JTreeTest24(){
    DefaultMutableTreeNode root = new DefaultMutableTreeNode("JavaDrive");

    DefaultMutableTreeNode swing = new DefaultMutableTreeNode("Swing");
    DefaultMutableTreeNode java2d = new DefaultMutableTreeNode("Java2D");
    DefaultMutableTreeNode java3d = new DefaultMutableTreeNode("Java3D");
    DefaultMutableTreeNode javamail = new DefaultMutableTreeNode("JavaMail");

    DefaultMutableTreeNode swingSub1 = new DefaultMutableTreeNode("JLabel");
    DefaultMutableTreeNode swingSub2 = new DefaultMutableTreeNode("JButton");
    DefaultMutableTreeNode swingSub3 = new DefaultMutableTreeNode("JTextField");

    swing.add(swingSub1);
    swing.add(swingSub2);
    swing.add(swingSub3);

    root.add(swing);
    root.add(java2d);
    root.add(java3d);
    root.add(javamail);

    tree = new JTree(root);
    model = (DefaultTreeModel)tree.getModel();

    JScrollPane scrollPane = new JScrollPane();
    scrollPane.getViewport().setView(tree);
    scrollPane.setPreferredSize(new Dimension(180, 120));

    JPanel p = new JPanel();
    p.add(scrollPane);

    text = new JTextField(10);
    JPanel textPanel = new JPanel();
    textPanel.add(text);

    JButton addButton = new JButton("Add");
    addButton.addActionListener(this);
    addButton.setActionCommand("Add");
    JButton deleteButton = new JButton("Delete");
    deleteButton.addActionListener(this);
    deleteButton.setActionCommand("Delete");
    JButton replaceButton = new JButton("Replace");
    replaceButton.addActionListener(this);
    replaceButton.setActionCommand("Replace");

    JPanel buttonPanel = new JPanel();
    buttonPanel.add(addButton);
    buttonPanel.add(deleteButton);
    buttonPanel.add(replaceButton);

    getContentPane().add(p, BorderLayout.CENTER);
    getContentPane().add(textPanel, BorderLayout.PAGE_START);
    getContentPane().add(buttonPanel, BorderLayout.PAGE_END);
  }

  public void actionPerformed(ActionEvent e){
    DefaultMutableTreeNode node = 
      (DefaultMutableTreeNode)tree.getLastSelectedPathComponent();

    if (node == null){
      return;
    }

    String action = e.getActionCommand();

    if (action.equals("Add")){
      String name = text.getText();
      if (!name.equals("")){
        node.add(new DefaultMutableTreeNode(name));
        model.reload();
      }
    }else if (action.equals("Delete")){
      node.removeFromParent();
      model.reload();
    }else if (action.equals("Replace")){
      String name = text.getText();
      if (!name.equals("")){
        node.setUserObject(new DefaultMutableTreeNode(name));
        model.nodeChanged(node);
      }
    }

    text.setText("");
  }
}

上記をコンパイルした後で実行すると次のように表示されます。

JTreeでデータモデルの更新を通知する

今回のサンプルではJTreeに表示されるノードの追加/削除/変更を行えるようになっています。

まず追加したい親ノードをマウスでクリックして選択した状態にしてから画面上部のテキストボックスに追加したいノードのテキストを入力し画面下部の「Add」ボタンをクリックして下さい。

JTreeでデータモデルの更新を通知する

JTreeでデータモデルの更新を通知する

ノードを展開してみると追加されていることが確認できます。

JTreeでデータモデルの更新を通知する

次にノードを削除します。削除したいノードをマウスでクリックして選択した状態にしてから画面下部の「Delete」ボタンをクリックして下さい。

JTreeでデータモデルの更新を通知する

ノードが削除されます。

JTreeでデータモデルの更新を通知する

JTreeでデータモデルの更新を通知する

最後に既存のノードのデータを変更します。変更したいノードをマウスでクリックして選択した状態にしてから画面上部のテキストボックスに新しいテキストを入力し、画面下部の「Replace」ボタンをクリックして下さい。

JTreeでデータモデルの更新を通知する

ノードが新しいデータに変更されます。

JTreeでデータモデルの更新を通知する

( Written by Tatsuo Ikura )

プロフィール画像

著者 / TATSUO IKURA

これから IT 関連の知識を学ばれる方を対象に、色々な言語でのプログラミング方法や関連する技術、開発環境構築などに関する解説サイトを運営しています。