Find location of a Jtree icon - java

Here's my problem. I want the pop up dialog to be triggered when a use clicks on the icon and icon only of a jtree tree node. I did some research and did not find any existing way to add mouse listeners on the icon (if there is please let me know!). Therefore, I decided to hack my way into it and use the Point object which I can get form mouseevent.getPoint() to figure out whether the mouse is on the icon. However, when I call Jtree.getCellRenct(row, col, includespacing) the location I get seem to be relative to the indentation of children node.
For example,
Parent
-Child1
-Child2
I get the same x coordinate by calling getCellRect() on all three nodes although what I really want is the x plus the indentation caused by "-" because mouseevent.getpoint() is not relative to the indentation.
Any idea how I can do this?
Edit:
I figured out a way. I call tree.getUI to get a BasicTreeUI object and call BasicTreeUI.getLeftChildIndent() and BasicTreeUI.getRightChildIndent(). Summing up these two integers will be the total indentation per level of the tree (or it seems to be so far). So I calculate the indentation by
(path.getPathCount() - 1) * (leftindent + rightindent).
It works for me so far although I am not entirely sure if this is good. For example I don't really know what left and right indent mean. Also in the source of BasicTreeUI it actually has a protected method
protected int getRowX(int row, int depth)
{
return totalChildIndent * (depth + depthOffset);
}
This method seems to get called by another protected method used to check if a location is within the area of tree expansion or collapse icon. I couldn't figure out much about what depthOffset is for. I guess it has something to do with whether root gets displayed or things of similar nature.
But still I am not feeling very comfortable doing it this way.. could somebody either tell me I'm good or that there is a better way to do this? :-)

Related

JTree representing a graph

I am using the JTree Swing utility to represent a Tree that actually have loops. I have a single node called root, but some of the children will eventually point back to other parts of the tree, thus not making it a true tree, but rather a graph.
My Java application keeps locking up, (no exceptions being thrown, no stack overflow... etc) when I try to use the little gray arrows to expand and contract parts of the graph.
My question is, does JTree require that none of the DefaulMutableTreeNodes not contain a loop?
If so, how do we represent something like that using a JTree utility. For example, when you are debugging an application say in eclipse, and you can infinitely use the variable tree in debug mode to keep on looking through a looped object. That is the behavior I am looking for.
Any suggestions?
I don't think it's a problem that nodes in a Jtree loop on themselves. Apparently you have a problem only with an "expand all" button, which makes sense because an expand all method will go recursively through the nodes until they have no sons.
Jtree does not have an expand all button by default, so I'm guessing yours is already customized...? My suggestion would be either remove the button, or customize the code to stop the expansion if findind a node that was already expanded higher in the hierarchy.

SWT: prevent Tree from expanding by doubleclick?

I have a problem with SWT Tree.
My situation is like this: I have a SWT Tree, which contains many TreeItems (Log entries), which contain TreeItems too. Those log entries have really long messages, which could not be shown in the TreeColumns at all. So my idea was: adding a Listener to the tree, which opens a new Dialog by DoubleClick, which shows the entries' details. So far so good.
If I do a double click on a item, it works. BUT: If I do a double click on a parent Item, it will expand (and thats good), but my double click Listener is active then as well and the Dialog will open.
That's not, what I want.
So, there are two solutions to the problem:
1) prevent the Tree from expanding/collapsing by double click automatically and implement the method by myself or
2) recognize, that the item was expanded and the event has to be aborted.
I do not really know how to do 1 or 2. Do u guys know that?
Thanks in advance.
Other answers did not work for me. This worked:
treeViewer.getControl().addListener(SWT.MeasureItem, new Listener(){
#Override
public void handleEvent(Event event) {
}});
I found this in a discussion in the Eclipse Community Forums: Disabling Treeviewer doubleclick expand/collapse.
When you look at this code you might be tempted to believe that it pretends to the tree control that your tree items have a size of zero, and as a result the tree control fails to detect that the double-click happened within the item, so it does not perform the double-click action. However, this is not what is actually happening. Instead, what this snippet does is that it leverages some weird code in the implementation of the tree control, which checks whether a listener has been added for SWT.MeasureItem, and if so, it deliberately avoids handling a double-click. This piece of code is even prefixed with a lengthy comment which a) fails to make sense and b) does not agree with what the code does. (Whatever.) So, bottom line is that by simply adding a handler for SWT.MeasureItem, and regardless of what the handler does, we are preventing the tree control from handling double-clicks. This is a prime example of Programming by Coincidence1.
1 The term "Programming by coincidence" was coined in the book The Pragmatic Programmer by Andy Hunt and Dave Thomas. It refers to relying on luck and accidental successes rather than programming deliberately.
If you are using TreeViewer, you could make use of IOpenListener
treeViewer.addOpenListener(new IOpenListener() {
#Override
public void open(OpenEvent event) {
}
}
There is another solution which works much better.
The problem with the solution from 'sambi reddy' was, that the tree was prevented from expanding by doubleclick, but it was prevented from expanding by clickling on the left handside cross as well.
My solution (that works well), was easy: I added a TreeListener, which listens to expanding/collapsing the tree and removed the expanding/collpasing implementation from the MouseDoubleClick-Listener.
No JFace TreeViewer - it works fine.

Eclipse Draw2d. Changing z order for IFigure

I am working through the examples in 'The Eclipse Graphical Framework (GEF)' book and the included Genealogy example(Draw2d chapters) seems to have the z order of figures messed up. When a figure is dragged or selected its z order remains unchanged which causes strange/unnatural behavior where the dragged figure can be dragged under other figures.
I would like to be able to change figures' z order when the figures are selected so they are moved to the top of the children list and appear at the top of the z dimension of the chart. What is the best way to do that?
The z-order of the figures in draw2d is defined either by order of addition (last figure on top) or can be set in Figure.add.
I guess the easiest (but probably not very efficient) way of doing what you want is removing the figure from the parent and adding it again. This will make it the last figure added, therefore also the top figure
I have found that removing the figure and adding back will screw up the event system such that if your intent, for example, is, when a figure is dragged to another location, you want to bring that figure to the front, the dragging is interrupted and you will no longer get any events for that figure. To bring a figure to the top, use the following code:
final IFigure child = <figure you want to bring to the front>;
final IFigure parent = child.getParent();
final List children = child.getParent().getChildren();
children.remove( child );
children.add( child );
child.repaint();
This is manipulate the raw list of children, moving the particular child to the fron of the z-order. Then, a repaint of the child is issued to show this change. This solution is specific to Draw2d, and has nothing to do with GEF.

Horizontally flipping a JTree

I want to visualize a set of linked objects by focusing on one element and showing all referenced objects and descendants in a tree to the right. That's business as usual.
But if i want to show the referencing objects (i.e. the objects pointing at my selected element) to the left of my selection i'd like to add a little twist. I want it to be a "reverse tree" - a tree with the structure nodes and lines on the right side.
That way the selected element (as root node) would be in the middle of the two trees and at least in theory it would be less confusing to the user.
Is there a way to flip the tree structure (not the text of course) horizontally in a JTree?
I'm pretty confident that there isn't an easy solution.
Probably the best you can do is, dig into the paint/repaint method of the tree until you find the place where the actual drawing is happening. Then create a tree with your own implementation of that.
Beware that you have to do the same thing for any kind of event handling, in order to find the correct node that was clicked on.
maybe you have look at JTreeTable,
It seems like you have to implement the TreeCellRenderer interface and make your own realization of getTreeCellRendererComponent and paint methods.
Excuse me for short answer and maybe wrong even. It just a small hint.

Creating a left-hand margin for a JEditorPane text box

Edit - in short, what I'm looking for is a reliable way to add a left margin to a JEditorPane (read on for the issues I'm having if you'd like).
I am trying to style some text in a JEditorPane, and have been fairly successful. The only problem I'm facing is that it seems impossible to create a margin.
Basically, I've extended PlainView and overridden the drawUnselectedText method. For now I just have it coloring the text red and changing the font. I've also overridden the drawSelectedText method to color the text.
This works consistently, whether text is selected or not, regardless of cursor position etc. - as long as I don't have a margin set.
However if I set a margin for the JEditorPane, the JEditorPane only works most of the time. The only case where it doesn't work is when a selection is made starting at the left-most character of any line. In that case, the margin is simply ignored and the selected text appears to the far left of the JEditorPane.
I know this is a pretty specific issue that most other people probably haven't experienced, and I have found nothing on the net about this, but I'm hoping someone here will have a solution.
Any ideas? Even anything that would allow me to set a margin using some other method than what I'm doing would be extremely helpful.
I gave up on finding an elegant solution to this problem. Basically I created a hack which tests whether or not the conditions exist where the bug will occur (selection from left, etc), and if they do it adjusts the rendering of the text.
I really don't like hacks as they are often bad for portability and maintainability, but this seems to work, so I suppose I'll abstract it away and hope it doesn't break anything.
In any case, it's working which is the key point. I didn't receive any answers, but I'm sure there are some people who at least tried to think of something, so thanks :)
Btw - if someone can come up with an elegant solution I will still accept that instead of my own answer (I can't anyways for two days).
Edit: This is one reason I like Java. Hacks are less likely to cause portability issues - even though this is related to rendering (it works through interaction with a Graphics object), it should still work on any OS.

Categories