Java ExplorerManager Filter - java

I have implemented https://blogs.oracle.com/geertjan/file-browser to show only folders (changed == in accept() to !=). However, no matter what I have done it only calls the FileFilterNodeChildren for the first level, the children of the root node. So what I get is the folders of the root node (the directory I want) but it show ALL files and folders below this level. I have put in statements that verify that the filter function is only called for the first level.
What do I need to do to filter the children of the first level and below?

Inside of createNodes() you need to wrap the child nodes with instances of FileFilterNode. Here is a revised version of createNodes():
#Override
protected Node[] createNodes(Node object) {
List<Node> result = new ArrayList<Node>();
for (Node node : super.createNodes(object)) {
if (accept(node)) {
// This is the only changed line
result.add(new FileFilterNode(node));
}
}
return result.toArray(new Node[0]);
}
This was tested in NetBeans 8.2 on Windows and works as expected. The "File Browser" displays a tree containing only folders at all levels.

Related

Programmatically arranging contents in aem 6.4

everyone. I'm new in working with aem. I'm using aem 6.4. My task is to programmatically sort the order of the contents of a cq:project in aem depending on the content of a JSON file.
The content of the JSON file should be set as the initial child instead of the children sorted by their creation date.
This is the current structure of my cq:page. If the child2 is the one indicated in the JSON file, it should be the first one to be displayed. The content of the JSON file is just the name of one child so even though there are 10 children, the content of the JSON file should always be the first one in the list.
I've spent hours researching on how I can implement this although I still can't find any solution. Any insights on how should I create this? Thanks!
As I understand it, you want a way to order a named child of a cq:Page to be first in the list.
This is possible because cq:Page is an orderable node. This would not be possible otherwise. you chan check any nodetype in CRX Explorer.
I think adding the bit about JSON complicates the question. You just need a simple method such as the following:
private void orderAsFirstChild(String childName, Node parentNode) throws RepositoryException {
if (parentNode.hasNode(childName)) {
// find current first child name
String firstChildName = Optional.ofNullable(parentNode.getNodes())
.map(NodeIterator::nextNode)
.map(node -> {
try {
node.getName();
} catch (RepositoryException e) {
e.printStackTrace();
}
return (String) null;
}) //
.orElse(null);
parentNode.orderBefore(childName, firstChildName);
}
}
You should probably clean this up a little, but this is the general idea using Node#orderBefore
This may helps -
Get the children from the parent node.(you will get 'iterator' convert it to list here-Convert Iterator to ArrayList)
Delete all child nodes now. And keep the back up of above list.
iterate through the list , identify the node which you want place first(by title or some other property) add that to a separate set(LinkedHashSet- to maintain order).
Now add the remaining items/nodes in the same order after your specific node in the above set.(you may need to iterate through again)
Now this Set has nodes/Resources in the order which you want, iterate , create nodes and save your changes.

"org.w3c.dom.DOMException: WRONG_DOCUMENT_ERR: A node is used in a different document than the one that created it."

I'm getting "org.w3c.dom.DOMException: WRONG_DOCUMENT_ERR: A node is used in a different document than the one that created it." when I call a WS method with a Java client.
It crashes in WSSecurityUtil.class inside org.apache.wss4j.dom.util, in this section of code:
Node firstChild = parent.getFirstChild();
if (firstChild == null) {
return (Element)parent.appendChild(child);
} else {
return (Element)parent.insertBefore(child, firstChild);
}
How can I fix this if the error seems (of course I'm not sure) to be in that package?
I will add client code if it's necessary.

Iterate through a fileSystem without using Binary tree or recursion

I have seen to similar questions here on this topic but none really helped me grasp the steps to solve this.
Given a queue, and a rootNode , how can I iterate through it? I understand first I have to enqueue the node I start with, but I am confused on how to implement the next() method. Also it has to be breadth-first traversal.
for the next() method I have this:
public File next(){
while(the peek() is a directory ("parent"){
use lists() to return the array of files
iterate thru those and add to queue
remove the first node
}
return peek();
It seems to work if I have a single file directory.
Also, I am looking for a pseucode not the code. I am just confused on whether I am on the right path or not.
If, for some reason, you insist on non recursive solution, although FileVisitor is definitely way to go with this in Java, breadth first search can be implemented non recursively.
This is general definition, marking is used to avoid circular referencing although you wont have that in this case:
Enqueue root of directories and mark root as discovered
while queue is not empty
dequeue and process element
discover adjacent edges - children
for every child, if not marked already and is a directory, mark and queue
To get children you need: String[] directories = file.list().
To make sure you are queuing directories and not files
call file.isDirectory() and enqueue only directories.
You do not need to do marking before queuing as you won't have circular reference between directories.
Edit:
Here is recursive breadth first search, you can modify it into iterative with the pseudo code above.
import java.io.File;
import java.util.LinkedList;
import java.util.Queue;
public class BFSRecursive {
public static void main(String[] args) {
File file = new File("D:/Tomcat");
Queue<File> files = new LinkedList<>();
files.add(file);
bfs(files);
}
private static void bfs(Queue<File> files) {
if (files.isEmpty())
return;
File file = files.poll();
System.out.println(file.getName());
String[] directories = file.list();
for(String child: directories) {
File childFile = new File(file.getAbsolutePath() +"/"+ child);
if (childFile.isDirectory())
files.add(childFile);
}
bfs(files);
}
}

Create a JTree from a list of dot-delimited Strings

I am creating an editor application, and I am having a problem with my menus. In the object menu, I want to display several objects types using a JTree. These object types are dynamically registered by plugins and follow this style:
trigger.button
trigger.lever
out.door.fallgate
trigger.plate
out.door.door
...
This list of names is unsorted and I want to build a TreeNode structure for a JTree like this:
trigger
button
lever
plate
out
door
fallgate
door
Additionally, if the user selects a leaf node, I need to recreate the object name (e.g. trigger.button) from the TreePath. Could someone please advise how this can be done.
In psuedocode, this is what you need to do...
public TreeNode buildTree(){
String[] names = new String[]; // fill this with the names of your plugins
TreeNode tree;
// for each plugin name...
for (int i=0;i<names.length;i++){
String currentName = names[i];
String[] splitName = currentName.split(".");
// loop over the split name and see if the nodes exist in the tree. If not, create them
TreeNode parent = tree;
for (int n=0;n<splitName.length;n++){
if (parent.hasChild(splitName[n])){
// the parent node exists, so it doesn't need to be created. Store the node as 'parent' to use in the next loop run
parent = parent.getChild(splitName[n]);
}
else {
// the node doesn't exist, so create it. Then set it as 'parent' for use by the next loop run
TreeNode child = new TreeNode(splitName[n]);
parent.addChild(child);
parent = child;
}
}
return tree;
}
This is only psuedocode - you'll need to do the work of implementing the TreeNode methods properly, etc. Give it a try yourself - if you have any more problems, create a question and show us that you've attempted to do it yourself, then we will be more willing to help you solve the minor problems.
see Oracle JTree tutorial
part Dynamically Changing a Tree, check the code example
similair idea

Trouble with inserting notes into a JTree

I have a JTree which is constructed with the following method:
(The BKMNode class extends DefaultMutableTreeNode, and theDataNode simply holds the data)
void populateTree(BKMNode parent) {
for (DataNode node : nodes) {
BKMNode treeNode = new BKMNode(node.name,node.fullName,null);
// check if this node was already added before
if (! existingNodes.contains(ip + "." + node.fullName)) {
existingNodes.add(ip + "." + node.fullName);
DefaultTreeModel model = (DefaultTreeModel)tree.getModel();
model.insertNodeInto(treeNode, parent, parent.getChildCount());
System.out.println("adding " + ip + "." + node.fullName);
}
node.populateTree(treeNode);
}
// some more non-relevant code...
When the tree is created at the application startup, everything is fine.
But once in a while my application adds nodes to the tree using the same method.
When the application attempts to add a new node to the tree in does print the text, but nothing changes on the GUI.
I tried calling JTree.invalidate(), validate(), repaint(), reload() but nothing seems to help.
The populateTree method is always called from the EDT.
Does anyone know what's the problems here?
Thanks a lot in advance!
Trust me, I tried using every invalidate, validate, repaint, reload method
Sorry, I don't trust you, people make silly mistakes all the time. That is why we need a SSCCE to see exactly what your are doing. Having said that, there is no reason to invoke any of those methods. invalidate(), validate() are used when you add/remove components from a Container, which you have not done. When you update a model, the model is responsible for notifying the view so the view can repaint itself.
but nothing changes on the GUI
What do you expect to change?
Inserting a node inserts a node into the model. If the parent node is expanded, then yes you should see the inserted node. However if the parent node is collapsed you will not see a change.
If you want to see the node after you insert it then you can use the tree.expandPath(...) method.
The basic code you posted works fine for me when I insert a default node containing a String value. Maybe the problem is your custom node? So the first thing you need to do is create a SSCCE that works with the default node. Once that works you replace the default node with your custom node. If it works, great. If not you know the problem is your custom node.
Based on the code provided it should work, so you need to give us more to work with.
Solved! I added some breakpoints at the "nodesWereInserted" method in the DefaultTreeModel's source and run the application with a debugger. It showed that the new nodes were added with a null parent! Further investigation showed the problem - the node.populateTree(treeNode); line added the new node without it being connected its indended parent.
This is the new (working) code. Thanks a lot for the help.
void populateTree(BKMNode parent) {
for (DataNode node : nodes) {
BKMNode treeNode = new BKMNode(node.name,node.fullName,null);
// check if this node was already added before
if (! existingNodes.contains(ip + "." + node.fullName)) {
existingNodes.add(ip + "." + node.fullName);
DefaultTreeModel model = (DefaultTreeModel)tree.getModel();
model.insertNodeInto(treeNode, parent, parent.getChildCount());
node.bkmNode = treeNode;
node.populateTree(treeNode);
} else {
node.populateTree(node.bkmNode);
}
} // for

Categories

Resources