I am making a program in Java and I have a SWT tree widget that the user is supposed to toy with via drag and drop.
Now the problem is that when the user drags and drops a branch, I want to change the branch item's parent to whichever treeItem it was dropped on, but there doesn't appear to be any way to do so. I could simply create a new treeItem, but there is no easy way to transfer the children, so I need to redefine all the children, and their grandchildren and so on recursively. It seems pretty klunky and inefficient to me that I need to remake the entire branch just to change the parent.
Is there any clean way to do this?
Well, the clean way is to separate view/widgets from model (as in MVC). In case of SWT, you should use TreeViewer and implement ITreeContentProvider. jFace will take care of creating tree nodes for you and you only need to update your model and refresh the viewer.
Related
I want to move a TreeItem with all of its child nodes from one parent to another. But I found no method for that.
Is really the only way to do this by removing the TreeItem and rebuild it at the new position?
That would be quite time-consuming because my node can have a lot of children and/or subtrees so I have to make a recursion...
In order to change the parent of a TreeItem your only option is to dispose of the item at its original position and re-create the item with its new parent.
As Greg mentioned, if you have a data model, you may want to use a TreeViewer which does the re-parenting for you.
Performancewise this isn't a problem, unless you have millions of items. But with such figures you would already run into performance problems while populating the tree initially.
Is it possible to drag and drop a container composite in SWT (Eclipse RCP)?
If it is can anyone explain how? Thanks!
Since this question has been asked many times around the SWT community, I've decided to make a blog post on this, with included source code. Check it out and don't hesitate to ask any questions if you are in doubt.
I think generally it should be possible, it is quite complicated however. Let's assume an application tailored to do so, what would be done
You select the composite in View A, trying to drag it to View B. First it is not possible to directly select a composite, you would have to provide a hook, by possibly taking a label within this composite and fetching the labels parent.
You then serialize the elements contained in the composite somehow.. anyway, what is it you want to transport?
You drop the data into View B, which gets your serialized String coming in. What to do with this String now?
You would have to dynamically create a new composite, resembling the structure of the original composite (that is where the String comes into play, which must contain all this information) and fill it with the information you wanted
You would then have to reload this view in order to show the new structure.
I think you first have to answer the question to what scenario you want to cover with draging and dropping a container before a deeper analysis can be done.
I have this pretty big project that I'm working on, graphic editor, and I've had some big problems working with swing components. However, now I have a programmers worst nightmare, a bug that is happening only some of the times.
If I try to select the elements in my JTree, whether when adding elements, or when selecting them when they are selected in diagram (JInternalFrame), some of them don't get expanded.
My structure is something like this, I have a workspace, containing projects and projects that contain diagrams. Diagrams hold all the elements I have, let's say circles, rectangles and so on, in folders (if they are circles, they are put in circles folder...).
Another thing to know is that I select my elements via setSelectedPath/Paths method of my JTree.
Some of the things that may help understanding what I do and what I tried:
I made sure my nodes know how to get to root. (getTreeModel.getPathToRoot returns good path)
I tried adding paths to trees selection model and to tree directly
I have set the trees expandsSelectedPaths to true
Nodes are selected when I expand my tree manually (they even expand afterwards), until I add new elements of type that caused problems
This happens about once when switching through 5 types of elements, and some stranger things happen when I try to add other type of element after I added one that made problems
I hope someone will know what to do, although I think this is very complicated problem. Please ask anything that may help you help me.
OK, thanks everyone for answering, but I have found a very simple workaround for this problem.
The thing was expanding has no effect if the last path component is leaf, for some reason.
What I did was simply making my leaf nodes return false for isLeaf method, and all my problems went away.
if addWhatever() to JTree firing the correct TreeModelEvent (fireChildAdded(), firePathChanged(), fireChildrenLoaded(), treeStructureChanged())
all changes for GUI would be moved to the BackGround Task(s), please look at SwingWorker or Runnable#Thread (most clear and easiest way), but Runnable#Thread required wrapping all output (Swing methods) to the invokeLater
I have a JTree that stores "ShipmentItem"s and the .toString() on them shows the quantity, then the name of the ShipmentItem. At some point I change the quantity of multiple items at once but the toString() doesn't refresh until I've actually clicked on that particular tree node. I don't want to have to extend JTree to use 'Property Fired' I just want to be able to refresh it so that it shows the update.
I tried jtree.setModel(tree.getModel()) this didn't seem to work at all.
When you change something to your TreeModel (which you do by adjusting the ShipmentItem objects) you must make sure your TreeModel fires the correct event. This will cause the JTree to repaint the correct part. If you for example started from the DefaultTreeModel, your extension should call nodeChanged when the object of the node has changed.
Note: you do not have to adjust the toString method for correct rendering. The concept you are looking for is a TreeCellRenderer (check the Swing tutorial for more information)
I am new to eclipse RCP, well as a matter of fact to java also. Have a very basic question.
I have a JFace TreeViewer. I want to expand a particular node in that. The catch is I only have the name of the node. and no information apart from that.
I tried using treeItem, compared its string with that of the node name that I have, thus I got the node. I tried expanding it in the contentprovider of the tree. But i am not getting the desired output. When I check it in the log i get that it is expanded but it doesnt show in the viewer. I am performing this in display.asyncExec method in the contentprovider.
I hope the question is clear.
JFace viewers were created so that developers wouldn't have to mess around with SWT widgets and could use higher level API instead. When using JFace's viewer/content provider/label provider you should be in control of what nodes are in your tree (thus when you say you only know the name, I assume you are using SWT Tree directly). You can read about JFace viewers from Eclipse help.
To expand a tree node use expandToLevel(Object elementOrTreePath, int level) method of TreeViewer (the level is relative to the node that is expanded, not the root of the tree).