JTree?

K

Knute Johnson

I've never played with the JTree component before but I've come across
an application for which it is particularly well suited. I need to edit
and add/remove elements from my JTree and then save the data to disk
between sessions. I think the data is held in the TreeModel
(DefaultTreeModel in my case). I thought I could just store the
TreeModel and use that to create a new tree when the program starts.
That doesn't work though. How do you normally keep data for use in a JTree.

Thanks,
 
C

Christophe Vanfleteren

Knute said:
I've never played with the JTree component before but I've come across
an application for which it is particularly well suited. I need to edit
and add/remove elements from my JTree and then save the data to disk
between sessions. I think the data is held in the TreeModel
(DefaultTreeModel in my case). I thought I could just store the
TreeModel and use that to create a new tree when the program starts.
That doesn't work though. How do you normally keep data for use in a
JTree.

Your idea is about just storing the TreeModel is correct, but what do you
mean by, "it doesn't work" ?

Serializing the model, and using it to reconstruct your JTree should work.

How are you doing this exactly?
 
J

Jim Sculley

Knute said:
I've never played with the JTree component before but I've come across
an application for which it is particularly well suited. I need to edit
and add/remove elements from my JTree and then save the data to disk
between sessions. I think the data is held in the TreeModel
(DefaultTreeModel in my case).

Consider creating your own TreeModel implementation. Usually this is a
much better fit with the specific data you wish to represent. You often
end up jumping through hoops using DefaultTreeModel.
I thought I could just store the
TreeModel and use that to create a new tree when the program starts.
That doesn't work though.


It should.
How do you normally keep data for use in a JTree.

Lately, XML. In the past, I serialized the tree model.

Jim S.
 
K

Knute Johnson

Christophe said:
Knute Johnson wrote:




Your idea is about just storing the TreeModel is correct, but what do you
mean by, "it doesn't work" ?

Serializing the model, and using it to reconstruct your JTree should work.

How are you doing this exactly?

I've attached the test code below. The objects that are added are
Serializable. I just attempt to write the TreeModel to a file with
ObjectOutputStream and then read it back when the program starts. Start
it at a command line to see the debugging messages.

Thanks again,

knute...

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;

public class TreeTest extends JFrame {
DefaultMutableTreeNode rootNode;
DefaultTreeModel treeModel;
JTree tree;

public TreeTest() {
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
try {
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("treeModel.dat"));
oos.writeObject(treeModel);
oos.close();
} catch (Exception e) {
e.printStackTrace();
}
System.exit(0);
}
});

Container CP = getContentPane();
CP.setLayout(new FlowLayout());

TreeModelListener tml = new TreeModelListener() {
public void treeNodesChanged(TreeModelEvent tme) {
System.out.println("treeNodesChaged");
}
public void treeNodesInserted(TreeModelEvent tme) {
System.out.println("treeNodesInserted");
}
public void treeNodesRemoved(TreeModelEvent tme) {
System.out.println("treeNodesRemoved");
}
public void treeStructureChanged(TreeModelEvent tme) {
System.out.println("treeStructureChanged");
}
};

try {
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("treeModel.dat"));
treeModel = (DefaultTreeModel)ois.readObject();
rootNode = (DefaultMutableTreeNode)treeModel.getRoot();
ois.close();
} catch (Exception e) {
e.printStackTrace();
rootNode = new DefaultMutableTreeNode("Client Project List");
treeModel = new DefaultTreeModel(rootNode);
}
treeModel.addTreeModelListener(tml);

tree = new JTree(treeModel);
tree.setEditable(true);
tree.getSelectionModel().setSelectionMode(
TreeSelectionModel.SINGLE_TREE_SELECTION);
tree.setShowsRootHandles(true);

CP.add(tree);

JButton addClient = new JButton("Add Client");
addClient.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
String str = JOptionPane.showInputDialog(tree,
"Enter Client Name");
if (str != null) {
DefaultMutableTreeNode childNode =
new DefaultMutableTreeNode(new Client(str));
treeModel.insertNodeInto(childNode,rootNode,
rootNode.getChildCount());
tree.scrollPathToVisible(new
TreePath(childNode.getPath()));
}
}
});
CP.add(addClient);

JButton addProject = new JButton("Add Project");
addProject.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
DefaultMutableTreeNode selectedNode =

(DefaultMutableTreeNode)tree.getLastSelectedPathComponent();
if (selectedNode != null) {
if (selectedNode.getUserObject() instanceof Client) {
String str = JOptionPane.showInputDialog(tree,
"Enter Project Name");
if (str != null) {
DefaultMutableTreeNode childNode =
new DefaultMutableTreeNode(new Project(str));

treeModel.insertNodeInto(childNode,selectedNode,
selectedNode.getChildCount());
tree.scrollPathToVisible(
new TreePath(childNode.getPath()));
}
}
}
}
});
CP.add(addProject);

JButton del = new JButton("Delete");
del.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
DefaultMutableTreeNode selectedNode =

(DefaultMutableTreeNode)tree.getLastSelectedPathComponent();
if (selectedNode != null &&
!selectedNode.equals(rootNode))
treeModel.removeNodeFromParent(selectedNode);
}
});
CP.add(del);

setSize(640,480);
setVisible(true);
}

public class Client implements Serializable {
String clientName;

public Client(String name) {
this.clientName = name;
}

public String toString() {
return clientName;
}
}

public class Project implements Serializable {
String projectName;

public Project(String name) {
this.projectName = name;
}

public String toString() {
return projectName;
}
}

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

Christian Kaufhold

Knute Johnson said:
I've attached the test code below. The objects that are added are
Serializable. I just attempt to write the TreeModel to a file with
ObjectOutputStream and then read it back when the program starts. Start
it at a command line to see the debugging messages.


Make classes Client, Project not non-static inner classes of TreeTest.

That way you have a reference

TreeModel -> TreeNode -> Client -> TreeTest -> JTree

so you end up also serializating the JTree.

I don't know exactly why the JTree doesn't de-serialize properly.



Christian
 
K

Knute Johnson

Christian said:
Make classes Client, Project not non-static inner classes of TreeTest.

That way you have a reference

TreeModel -> TreeNode -> Client -> TreeTest -> JTree

so you end up also serializating the JTree.

I don't know exactly why the JTree doesn't de-serialize properly.



Christian

Christian:

That fixed it. Thanks very much. I don't understand why having Client
and Project as inner classes should make a difference. I thought a
class was a class.

Thanks again,
 
C

Christophe Vanfleteren

Knute said:
Christian:

That fixed it. Thanks very much. I don't understand why having Client
and Project as inner classes should make a difference. I thought a
class was a class.

Thanks again,

Yes and no: non static inner classes actually contain a (implicit) reference
to their outer class (since you can't have an inner class without an
instance of it's outer class).
As Christian said, when you serialize a Client instance, you'll also
serialise the entire TreeTest class. This doesn't happen when Client is a
regular public class.
 
K

Knute Johnson

Christophe said:
Yes and no: non static inner classes actually contain a (implicit) reference
to their outer class (since you can't have an inner class without an
instance of it's outer class).
As Christian said, when you serialize a Client instance, you'll also
serialise the entire TreeTest class. This doesn't happen when Client is a
regular public class.

That makes sense. I did try making TreeTest Serializable but it didn't
work. I may try playing with it some more for fun.

Thanks,
 
A

adhirmehta41

instead of serializing jtree directly into a file u can do one thing
is that convert your jtree information into xml file and pass this xml
file where u want and if require u can again make a jtree. advantage
of this is that it is standard techniques and many xml parsers are
available for this.second one its simplicity no burden on your side.
 
B

BarryNL

instead of serializing jtree directly into a file u can do one thing
is that convert your jtree information into xml file and pass this xml
file where u want and if require u can again make a jtree. advantage
of this is that it is standard techniques and many xml parsers are
available for this.second one its simplicity no burden on your side.

In fact, I'd seriously consider writing an Adapter (or Bridge if complex
enough) to present the XML Document object as a TreeModel. Then you
always have an in memory XML Document as your underlying model data.
 
C

Chris Smith

BarryNL said:
In fact, I'd seriously consider writing an Adapter (or Bridge if complex
enough) to present the XML Document object as a TreeModel. Then you
always have an in memory XML Document as your underlying model data.

I agree that this is an attractive option for editing a persistent XML
data model, and it's one I've used in an application for years, and
which has saved a lot of synchronization effort between an artifical
model and the XML. It's worth noting, though, that a reasonable use of
this technique requires an implementation of the DOM Events
specification, which is not available through the standard JAXP parser
distributed through the J2SDK. Xerces works fine.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Extra Row in JTree 6
[SWING] Problem with JTree 2
JTree bizarreness 0
Refreshing JTree 6
change icon in jtree 0
JTree problem 0
JTable within JTree 1
Jtree renderers 0

Members online

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,743
Latest member
WoodrowMea

Latest Threads

Top