I've been working on a file server program for a while, and thus far I've been able to avoid posting something here for help. But I cannot find anything on my problem and I am very confused.
I've added a popup menu with the option to create new top level folder, which really just creates a node and, after its edited sends its name to the server to create the folder. While I've got all of the editing working correctly and have the upload working, I am having a problem.
I change the JTree to be editable when the folder is created, and a while loop that continues until that node is not the one being edited, at which point it removes edit-ability from the JTree.
public static void newTopFolder(){
DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot(); //now we have the root
DefaultMutableTreeNode newFolder = new DefaultMutableTreeNode("New Folder");//will change to increment for duplicates
DefaultMutableTreeNode empty = new DefaultMutableTreeNode("< empty >"); //easier way to have empty folder, don't worry about it
tree.setEditable(true); //sets to editable
model.insertNodeInto(newFolder, root, root.getChildCount()); //adds folder to tree
model.insertNodeInto(empty, newFolder, newFolder.getChildCount()); //adds empty to tree, not real file
TreePath nfPath = getPath(newFolder); //so we don't call getPath extra times
tree.startEditingAtPath(nfPath); //automatically selects folder to edit
System.out.println(tree.getEditingPath().toString()+":"+nfPath.toString()+";"); //returns [\user\, New Folder]:[\user\, New Folder]; which shows the two are equal
while(tree.getEditingPath().equals(nfPath)){//when nothing is selected null if nothing is being edited, and path to other objects if selected
}
tree.setEditable(false); //changes to node will have been committed and editing disable
sendFolderToServer(nfPath); //sends folder to server after formatting as a String used in new File(Paths.get(nfPath));
}
Unfortunately, the while check tree.getEditingPath().equals(nfPath) always returns true, thus it remains editable.
But I don't understand why it remains true, it clearly shouldn't. In case it helps/ changes anything, this is run in a separate thread (otherwise the while loop would stop the GUI from rendering)
So what should / can I do, is there a better way to do this, or at least one that works?
UPDATE:
While I haven't found a solution to the clear problem above, If I instead test for tree.isPathSelected(nfPath) That works fine and the tree is set to not be editable afterward!
Get editing path doesn't remove the variable of the path being edited... Therefore, after it's done editing the most recently edited path is still the correct path.
Instead using tree.isPathSelected(path) will work
Related
Heyy. I am writing a tool in Java which deletes non-whitelisted files. Don't ask. It lists a directory that the user selects with the JFileChooser. This works well, all filenames are listet in a JList (in my case inside a JScrollPane) and displayed inside of the frame.
Now i want to read filenames from a .txt file and check if they match the names in the list. The reading and comparing is no problem. But i would like to set a green background if the file matches one of the files inside the .txt file. If not, then the background of the displayed item should be red. But how can i change these backgrounds for one line if its even possible?
Simple, set a custom ListCellRenderer to your JList using:
list.setCellRenderer(myListCellrenderer);
Now inside the overridden method getListCellRendererComponent() do something like this:
public Component getListCellRendererComponent(.....) {
Component c = super.getListCellRendererComponent();
c.setBackGround(Color.blue)
return c;
}
When the logic determines you should show the row as green (when the file names are equal), you also have the option of setting the state on the backing object of the row and test it for that state within getListCellRendererComponent(), setting the background green if the state is correct. Again, you have the option of setting a Swing Timer to revert the state on the backing object.
basically I am working with a treeviewer in Java (org.eclipse.jface.viewers.TreeViewer).
Now my problem is, that I want to add an childelement/ item to an existing knot.
First of all my tree looks like this:
Knot A
Knot B
Knot C
>child1
>child2
These children(child1, child2) arent added manually, they are generated before I get my hands on the tree itself.
I create the treeviewer:
viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL
| SWT.V_SCROLL);
I populate the treeviewer:
viewer.setInput(....elements());
which generates the state from above.
viewer.getTree().getItem(0) returns the correct knot A of my tree.
But I cant add a new child to an existing knot.
I tried the following and other things:
TreeItem newItem = new TreeItem(items[0], SWT.NONE); and
viewer.add(items[0], newItem); with a newly created item
viewer.refresh();
Theoretically I could manipulate the arrayList which populates the treeviewer in the first place but that would be really bad I think.
I really do not know what I am doing wrong right now.
I guess it is a quite silly question. If that is the case, then I am sorry.^^
Thank you for your help, I am grateful for every hint that you can offer.
Updating your 'model' (the data you give to setInput) is the correct way to update the tree. Call TreeViewer.refresh() or TreeViewer.refresh(element) to get the tree viewer to update the tree from the model.
When you are using TreeViewer you never create TreeItem objects - the viewer does that. Everything you pass to the refresh, update, add ... methods are objects from your model not TreeItems.
I'm currently developing an application that will allow people to download the files from the online FTP repository, I have it connecting perfectly with Apache Commons, My only trouble is making a JTable out of it.
I know how to create a JTree, My problem is adding the nodes when they are called (Someone presses the plus icon, Load files in sub directory)
Also determining whether they are leafs... I'm sorry, I'm so lost at the moment!
If it were me, i'd remove the plus button, and just load sub directories when you get tree will expand events.
So What you could do, is populate the top level node, with a Stub node under it, and show the tree with the top level node, non-expanded. When the user expands it, you will get the tree will expand event. Look at the child, and see if it's a Stub node. If it is remove it, and use apache commons to load the children, populating each one, and each one with it's own stub node.
What is a stub node? Just a node that somehow tells you that this node is a placeholder. It means that you haven't tried to load children yet. Most likely this Node class will be a special class called StubNode or something. Of course you only need to add Stub nodes to directories, not files, as you won't be expanding files.
http://www.java2s.com/Tutorial/Java/0240__Swing/TreeWillExpandListener.htm
UPDATE: It doesn't have to be using static files. Is using a global variable string and listening to if that changed in length possible?
WHAT AM I TRYING TO DO: Basically, I am trying to represent a visual tree representation of an xml document that is rendered on the other Jpanel. When I select node on this rendered xml document, I want to add that xml node onto the visual tree. So essentially, the rendered componenet and the visual tree componenent share the same xml file/variable.
THE PROBLEM (I am open to alternate suggestions) :
I have a visual tree generated by the following method using org.apache.xerces.parsers.SAXParser.
It reads an xml file and returns the scrollPane component to be rendered on screen.
I need to be able to add or remove nodes and edit. So when I click a button, it will add a node to the visual tree. However, I think there needs to be some event listener when the xml file has been updated to quickly draw the tree. This might be inefficient (?) because it requires redrawing the tree everytime xml file change event happens?
private static Component createTree() {
DefaultMutableTreeNode top = new DefaultMutableTreeNode("test"));
SAXTreeBuilder saxTree = new SAXTreeBuilder(top);
try {
SAXParser saxParser = new SAXParser();
saxParser.setContentHandler(saxTree);
saxParser.parse(new InputSource(new FileInputStream("test1.xml")));
}catch(Exception ex){
ex.printStackTrace();
top.add(new DefaultMutableTreeNode(ex.getMessage()));
}
JTree tree = new JTree(saxTree.getTree());
JScrollPane scrollPane = new JScrollPane(tree);
return scrollPane;
}
First store the modification time of an XML file in a temporary variable while drawing the tree for the first time then Use a thread or TimerTask to keep track of the modification time ,if there is any change in modification time compared to temporary variable that means XML file is modified.call your tree view generation code.
A change event for files doesn't exist. You only option is to write a polling thread calling java.io.File.lastModified() on your file. Depending on the situation that might be enough and the performance penalty not too high.
If you want you can also use this library from Apache commons
I have two JTrees instances (leftTree and rightTree). User can select some nodes from left tree and add the same to right tree. I have the below code in add button action listener to expand and select the node in rightTree after the node has been added.
rightTree.updateUI();
TreePath[] paths = leftTree.getSelectionPaths();
if (null != paths && paths.length > 0)
{
TreePath path = paths[0];
DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
rightTree.scrollPathToVisible(new TreePath(node.getPath()));
rightTree.setSelectionPaths(paths);
}
leftTree.clearSelection();
This code seems to work fine for some nodes but it cannot work for some other nodes in leftTree. The problem is even after the above code is executed, the rightTree is in collapsed state and I cannot see the selected node.
I have tried using other methods in JTree like setExpandsSelectedPaths(true), expandPath(new TreePath(node.getParent())). Also, tried calling rightTree.repaint() or rightTree.validate() after the above code is executed. But still the problem exists. But rightTree.isExpanded(new TreePath(node.getParent())) retruns true;
My tree is about 7-8 levels deep. Please help me to solve this and let me know if you need more information.
For me the approach is incorrect. TreePath is in fact sequence of nodes from the current node to top most parent. In other words TreePath from node is created by calling getParet() till tull is reached.
So if you get a node from one tree and create path the path is sequence of node in the original tree and the path is futile in the second tree because some nodes in the path just don't exists in the target tree model.
You need to get selected node and find an appropriate one in the second tree. Guess a node with the same user object. The for the found node in the target tree (if we found it) create TreePath and select/expand.