I have a ftp program that retrieve folder data each time expanded. It does this by using a model like this:
private void FilesTreeTreeExpanded(javax.swing.event.TreeExpansionEvent evt) {
String path = new String("");
DefaultMutableTreeNode chosen = (DefaultMutableTreeNode) evt.getPath().getLastPathComponent();
String[] pathArray = evt.getPath().toString().replaceAll("]", "").split(",");
for (int i = 1 ; i < pathArray.length ; i++) path += "/"+ pathArray[i].trim();
// i were aded chosen.removeAllChildren(); without success
ftp.GoTo(path);
ArrayList listDir = null;
listDir = ftp.ListDir();
ArrayList listFiles = null;
listFiles = ftp.ListFiles();
DefaultMutableTreeNode child = null , dir = null , X = null;
//this will add files to tree
for (int i = 0; i < listFiles.size(); i++) {
child = new DefaultMutableTreeNode(listFiles.get(i));
if(listFiles.size() > 0)
model.insertNodeInto(child, chosen, 0);
}
//this will add dirs to list
for (int i = 0; i < listDir.size(); i++) {
X = new DirBranch("در حال دریافت اطلاعات ...").node();
dir = new DirBranch( (String) listDir.get(i)).node();
dir.add(X);
if(listDir.size() > 0)
model.insertNodeInto(dir, chosen, 0);
}
FilesTree.setModel(model); //this is my Swing JTree
}
the problem is every time i expand the JTree it duplicate list of files and folders. so i tried to use chosen.removeAllChildren(); # the top of the code but it didnt remove anything. what should i do?
Your model is correct, but JTree is operating on old information.
The removeAllChildren() method removes the children, but it does not fire any events and the model.insertNodeInto() does fire insert events. So, JTree sees the nodes being added, but never sees the nodes being removed.
After adding the new children, try calling model.reload(chosen) to invalidate the tree below chosen.
Since you will be reloading the branch, you can also change model.insertNodeInto(dir, chosen,0) to chosen.insert(dir,0). That reduces the number of events posted.
Calling removeAllChildren() will remove the children from the node. There must be something else happening here that is creating duplicates. Make sure you are not calling anything twice and that you are refreshing the display of the tree.
In my application also i just fact the same problem. For that i just used the following code.
JTree.removeAll();
JTree.setModel(null);
It remove all child nodes from my Jtree.
Related
I have to develop a Dijkstra Alogirthm in Java and I have a question to Dijkstra in a circle.
So for a Tree or a normal graph without a loop it works.
So I have a Status White means not found, gray = found but not dealt with and black means done.
So when I have a loop I tryed a if (next.status == Node.Black) but then he didn't found all nodes.
So the question is, how can I add a loop detection and found all nodes?
Thanks for help and tips
best regards
witar7
PS: the if (next.equals(startNode) was only an idea to stop the loop.
public void populateDijkstraFrom(Node startNode) {
this.resetState();
PriorityQueue<Node> distanceQueue = new PriorityQueue<Node>();
for (int x = 0; x < nodes.size(); x++) { // for each node
nodes.get(x).distance = Double.POSITIVE_INFINITY; // set distance to inf
nodes.get(x).predecessor = null; // delete existing predecessors
}
startNode.distance = 0.0; // set distance from startNode to zero
startNode.status = Node.GRAY; // mark startNode as active
Node current = startNode;
distanceQueue.add(current); // add startNode to prio queue
while (!distanceQueue.isEmpty()) { // while contains elements
current = distanceQueue.poll(); // set current to head of queue
current.status = Node.BLACK; // mark head as settled
for (Node next : current.getAdjacentNodes() ) { // get all adjacent nodes
if (next.equals(startNode)) {
break;
}
next.status = Node.GRAY;
// stopExecutionUntilSignal();// mark status as found
distanceQueue.add(next);
if (distanceQueue.contains(next)) {
if (next.distance > current.distance + current.getWeight(next)) { // if the found distance is smaller then the existing one
next.predecessor = current; // change distance in node
next.distance = current.distance + current.getWeight(next); // set predecessor
}
}
}
}
this.clearMarks();
}
PS: the if (next.equals(startNode) was only an idea to stop the loop.
There's no need to do this, your while condition will terminate anyway when it can't find anymore unvisited adjacent nodes. You just have to check whether current visited node status is BLACK and if yes, don't add it to the queue (it's already been visited before).
P.S.: I don' think you need GRAY status, just BLACK or WHITE. Deal with the node right away, no need to delay.
I am using a JTree in which new nodes needs to be inserted dynamically to the root(consider adding children to root). Once the user selects a node and clicks a button, the new node needs to be added after the selected node. If none of the node is selected then it adds the new node at the end of the tree. Below is my code
public void addNodeToRoot(TestCase testCase) {
DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(testCase.toString());
int currentNoOfChildren = getTcBuilderTree().getModel().getChildCount(getTcBuilderTree().getModel().getRoot());
TreePath currentSelection = getTcBuilderTree().getSelectionPath();
int currentIndex=0;
//if the user has not selected a node add the test case at the end of the tree
if (currentSelection == null) {
currentIndex = currentNoOfChildren;
}
//if user has selected a node then insert the new node after the selected node
else {
int[] currentSelectedIndex = getTcBuilderTree().getSelectionRows();
currentIndex = currentSelectedIndex[0];
}
treeModel.insertNodeInto(childNode, getRoot(), currentIndex);
}
it works all fine but the code gives an exception when there are child nodes in the level 3 as well. The reason is when the tree has more levels and when its expanded then the currentIndex gives unexpected number (it counts all the indexes in all levels up from the root to the selected node) and the app gives ArrayIndexOutOfBoundsException since the currentIndex becomes greater than currentNoOfChildren
If the tree is not expanded then everything happens correctly. Please let me know how to resolve this. Is there any other way to get the no of children of a specific level in the tree?
Maybe code below can resolve your problem.
int currentNoOfChildren = getTcBuilderTree().getVisibleRowCount();
I found some details on the internet for this problem but the solution does not seem to work.
I want to be able to expand all the nodes ( including the leaf nodes ) of a JTree. This is the code I have so far.
tree = new JTree(treeModel);
tree.setShowsRootHandles(true);
tree.setEditable(true);
tree.addTreeSelectionListener(treeSelectionListener);
tree.addMouseListener(mouselistener);
tree.setCellRenderer(new FileCellRenderer());
for (int i = 0; i < tree.getRowCount(); i++) {
tree.expandRow(i);
}
This however does not expand all the leaf nodes. What I get is IMAGE A but what I want is IMAGE B:
Use a recursive call, as in the following sample:
private void expandAllNodes(JTree tree, int startingIndex, int rowCount){
for(int i=startingIndex;i<rowCount;++i){
tree.expandRow(i);
}
if(tree.getRowCount()!=rowCount){
expandAllNodes(rowCount, tree.getRowCount());
}
}
I stumpled upon a Problem with Java wich seems very strange so I didn't found anything in the internet.
I want to make a little program wich just searchs for specific files to delete them. (Not at this point yet) Right now, the Program just searchs for all files in the dir and in the subdirectories. It works but sometimes (about 50/50) the JList, I use to show the files, does not show anything. (This is the problem I have) I dont change any Files, nothing changes to the .jar, it just does not show the elements sometimes.
I also checked if the array is maybe empty, there are elements in it, even when the List does not show them. It would be greate if you know a solution to this. Thank you.
Here is the Code: (Just so you know, I did not wrote the function GetAllFiles by my own)
Variables:
JList output;
JScrollPane outputScrollPanel;
DefaultListModel outputContent;
String[] files;
int fileIndex;
File source;
Constructor:
add(output = new JList());
outputContent = new DefaultListModel();
output.setModel(outputContent);
add(outputScrollPanel = new JScrollPane(output));
outputScrollPanel.setBounds(20, 20, getWidth() - 50, getHeight() - 40);
files = new String[0];
fileIndex = 0;
SearchFiles();
The SearchFiles-function together with the GetAllFiles (I did my best, not taking redundant Names ;) )
private void SearchFiles() {
source = new File("");
GetAllFiles(source);
for(int i = 0; i < fileIndex; i++) {
outputContent.addElement(files[i]);
}
}
private void GetAllFiles(File dir) {
File[] fileList = dir.getAbsoluteFile().listFiles();
if (fileList != null) {
for (int i = 0; i < fileList.length; i++) {
if (fileList[i].isDirectory()) {
GetAllFiles(fileList[i]);
} else {
if(fileIndex%100 == 0) {
IncreaseFileListSize();
}
// i am so proud of this one: (it just adds the relative path + file name to the files-array
files[fileIndex] = fileList[i].toString().substring(source.getAbsolutePath().toString().length()+1);
fileIndex++;
}
}
}
}
Im learning Java and Im creating a memory type game where you have to find two equal cards.
I have created a Window etc etc but my problem is adding multiple JButtons to it. (my cards are JButtons with icons). I have commented my code where my problem is.
//Get the images.
private File bildmapp = new File("bildmapp");
private File[] bilder = bildmapp.listFiles();
//My own class extending JButton
Kort[] k = new Kort[bilder.length];
for(int i = 0; i < bilder.length; i++){
k[i] = new Kort(new ImageIcon(bilder[i].getPath()));
}
//Later in my code:
int sum = rows * columns;
Kort[] temp = new Kort[sum];
//My function to randomize.
Verktyg.slumpOrdning(k);
//***********************//
//Trying to fill a array from K (which contains all cards) so my temp contains SUM cards and SUM/2 pairs
for(int i = 0; i < sum/2; i++){
temp[i] = k[i];
temp[i+sum/2] = k[i];
}
//Problem is that i only get SUM/2 (half of the cards) cards, not the 16 (8 pairs) i would like to add in this case
//SYNLIGT = VISIBLE.
for(int i = 0; i < sum; i++){
temp[i].setStatus(Kort.Status.SYNLIGT);
j.add(temp[i]);
}
Your code ends up adding each Kort object to the container twice, since the array temp contains two references to each Kort. When you add a Kort a second time, it moves to the second location. A Component can only appear in one place at a time.
You may not add the same widget twice. You need two separate buttons (but you may use the same icon on both).
You have to create sum JButton objects not sum/2; otherwise 2 buttons are the same and therefore only displayed once.