I asked this question before, but I feel like I didn't give too much of code to explain my problem well enough.
This is what I want to do:
I have a list of objects called User
. Each object contains two fields - username
and password
. I created a method to build a jtree with usernames like this:
public class UserTreeBuilder implements TreeWillExpandListener {
private JTree userTree;
DefaultMutableTreeNode dummyParent;
public JTree build(List<User> list){
DefaultMutableTreeNode top = new DefaultMutableTreeNode("");
createNodes(top, list);
userTree = new JTree(top);
userTree.getSelectionModel().setSelectionMode
(TreeSelectionModel.SINGLE_TREE_SELECTION);
userTree.setRootVisible(false);
userTree.addTreeWillExpandListener(this);
return userTree;
}
public void createNodes(DefaultMutableTreeNode top, List<User> list) {
DefaultMutableTreeNode category = null;
DefaultMutableTreeNode user = null;
category = new DefaultMutableTreeNode("User");
top.add(category);
for(User ui : list){
user = new DefaultMutableTreeNode(ui.getUserName());
category.add(user);
}
}
@Override
public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) userTree.getLastSelectedPathComponent();
String nodeName = node.toString();
System.out.println("NODE TO STRING: "+nodeName);
if (node == null)
//Nothing is selected.
return;
}
@Override
public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException {
throw new UnsupportedOperationException("Not supported yet.");
}
It works good, I see the list as:
(folder icon) users
(dot icon) user1
(dot icon) user2
(dot icon) user3
etc.
So the accounts user1
, user2
, etc. are the lowest nodes.
I have a method that gets the username as a parameter and returns a list of things that belongs to this user. It looks like this:
public ArrayList<Things> fetchThings(User user){
List<Things> list = new ArrayList<Things>();
.
.
.
return list;
My question is - how can I fetch things for a specific user (invoke my method fetchThings) when someone clicks the given user on my original jtree and then display those things as children nodes assigned to that user?
For example, someone clicks user2
and this is what he sees:
(folder icon) users
(folder icon) user1
(folder icon) user2
(dot icon) thing1
(dot icon) thing2
(dot icon) thing3
.
.
.
(folder icon) user3
etc.
I tried to use lazy loading of children from this page https://docs.oracle.com/javase/tutorial/uiswing/components/tree.html but I cannot make it work. Can you please help me with my implementation?
If you had read the JTree
JavaDocs you would know that you can get the node that was clicked by using something like...
MouseListener ml = new MouseAdapter() {
public void mousePressed(MouseEvent e) {
int selRow = tree.getRowForLocation(e.getX(), e.getY());
TreePath selPath = tree.getPathForLocation(e.getX(), e.getY());
if(selRow != -1) {
if(e.getClickCount() == 1) {
mySingleClick(selRow, selPath);
}
else if(e.getClickCount() == 2) {
myDoubleClick(selRow, selPath);
}
}
}
};
You can use the TreePath
to getLastPathComponent
which will return an Object
, which in your case, you can cast it to a DefaultMutableTreeNode
If you had read the JavaDocs for TreeWillExpandListener
, TreeeExpansionEvent
and TreePath
, you will know that when treeWillExpand
is called, you can get the node which will be expanded by using TreeExpansionEvent#getPath#getLastPathComponent
, something like...
@Override
public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException {
DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) event.getPath().getLastPathComponent();
System.out.println(treeNode);
}
From there you can simply call whatever functionality you need to in order to obtain the information you need to populate the DefaultMutableTreeNode
in question
Your user
DefaultMutableTreeNode
will need to override the isLeaf
method and return false
, this will allow the node to be "expandable", something like...
for (User ui : list) {
user = new DefaultMutableTreeNode(ui.getUserName()) {
@Override
public boolean isLeaf() {
return false;
}
};
category.add(user);
}