Assinging different icons to different nodes in a JTree - java

Is it possible to assign different icons to different nodes in a JTree using DefaultTreeCellRenderer.setOpenIcon()? Thanks.

The same cell renderer instance is used to render all the cells of the tree. The open icon is the little + symbol, or triangle symbol at the left of every tree node which allows to expand it (i.e. see its child nodes). I doubt this is the icon you want to change. It would be rather strange not to use the same one for all the nodes.
If you want to display a custom icon for a specific node, create a subclass of DefaultTreeCellRenderer, override the getTreeCellRendererComponent method, decide which icon to display based on the value passed to the method, and call setIcon.
See http://download.oracle.com/javase/tutorial/uiswing/components/tree.html#display for a similar example (which customized the tooltip, and not the icon, but the idea is the same).

Related

CodeNameOne - React on Tree expansion or collapse

I'm using a subclass of the Tree class in my project. I'm having two problems. First I would like to change the text of the not-leaf nodes when they expand or collapse. Second when expanding some nodes the tree exceeds the screen and even if scrollable is set to true, I can not scroll all the way to the bottom. To be specific the tree always shows as many nodes as in the beginning. If it begins with 10 nodes, then after expanding I will only be able to scroll the ten top nodes and not the whole tree.
While trying to figure out both points I looked for a callback on expansion/collapse, but it seems to be private. Is there any way to add a listener on expansion/collapse or other way to solve my issues?
Tree should be placed in a non-scrollable hierarchy where it can take responsibility over the scrolling e.g. in the center of a border layout on the Form.
You can override the createNode method of Tree and build any type of Component you want. It can change it's text when it's expanded based on the events and do anything you want.

How to add an image while we drag n drop tree item?

I have a tree with number of childs and i want to drag and drop these child items on a vertical panel. Right now its working fine.The only thing i want to know is can we add an image in the place of small icon which comes at the time of dragNdrop.
You need to override the newDragProxy() method of the PickupDragController in order to provide your own proxy widget (say, an image) when the drag starts.
Do note that you also need to use setBehaviorDragProxy(true) to allow dragging proxies instead of the original widgets (i.e., the original widgets will stay in place, and you simply drag a proxy of it, that you can style as you wish).

JTree with left and right-aligned text in cells?

What I'm trying to do is create a JTree with each cell containing normal text but also containing a right-aligned text for each cell (right-aligned to the edge of the tree, regardless of the hierarchy level).
I've tried creating my own TreeCellRenderer, but the cells' sizes are not being updated. I also tried this idea with a custom tree UI but am experiencing similar issues.
I also have tried creating a custom component with a JPanel "glued" to the right of the tree. This has been the most successful, but I have been unable to have the tree cells extend to the right and touch this extra panel:
alt text http://img718.imageshack.us/img718/3676/problem.png
You could try to use a JXTreeTable, from the SwingX package.
jxtreetable example http://blogs.sun.com/geertjan/resource/outline-tim-browser.png
You would define then such an object with two columns (one for the tree, to other for the right aligned text), and it should work out fine.
To prevent it from looking like a table, though, I would recommend you to deactivate the header (setTableHeader(null)), and use their "packing" methods, to have the columns on optimal size.

Swing: Floating panel next to the selected item in a JComboBox

I've created an app with a small window (the size of a combo box). I need to create a floating panel that sits outside the window, next to the selected item in a JComboBox. (See attached image).
I've been reading about the JComboBox.setRenderer(customRenderer) etc. But was just wondering before I go down this path, whether it is at all possible to render something outside the window. I suspect it is, as the combobox itself manages to render it's popup list outside the window.
I'm very new to Swing, so any advice would be appreciated.
It's not possible with the custom renderer since Swing components are light weight. That is, Java is given a native window and all the component drawing takes place in that window. In your case, that is the JFrame containing the combo box.
What you can do though is create a new undecorated window and set it's location accordingly and draw whatever you want inside it.
EDIT: When Java needs to paint outside it's window bounds (like the case of pop up messages or combo boxes drop downs) if the component falls inside the bounds it uses the swing light weight mechanism. But if the component falls out side the bounds it is automatically substituted with a awt heavy weight component that has it's own native drawing surface outside the active window.
I've implemented similar idea using combobox renderers and tooltips on them. Content of every item's tooltip can be customized and rendered using HTML. Location of the tooltip can be set outside of the item itself thus creating design very similar to the one presented in your question.
Here is the starting point for you:
http://www.java2s.com/Code/Java/Swing-Components/ToolTipComboBoxExample.htm

Can findComponentAt() work before a JComponent is painted?

I am working on a GUI where the JComponents are "stamped" on the screen. In other words, the actual components aren't displayed, but images of the components. This is a graph, where the nodes of the graph are custom Swing components - or rather stamped images of Swing components.
Now I want to display tooltips for specific components within my nodes.
To do this, I create a JComponent that is identical to the one displayed and using the mouse x and y values, I ask findComponentAt() for the proper component. This doesn't work very well. If I reuse JComponents for the nodes, it gets confused if I try to get a tooltip for a node that is a different size than the last one painted. If I create a new JComponent for each node and a new one when calculating the tooltip, the initial size of the new one is 0,0. I can set the size using the getPreferredSize() calculation, but that still doesn't work. The root JComponent (a JPanel) has the right size, but none of it's children have any size yet.
A sample of the tooltip calculation code:
// Get a component that matches the stamped component
JComponent nodeComponent = getNodeComponent();
// These next two lines get the size right
nodeComponent.setSize(nodeComponent.getPreferredSize());
nodeComponent.revalidate();
Component componentTop = nodeComponent.findComponentAt(relativeX, relativeY);
componentTop comes back as the root JComponent no matter what x and y values it is passed.
So is it possible to get Swing to properly calculate the size and locations of the JComponents without actually painting them?
You have images of your components in the graph they have to have their sizes to be able to paint correctly.
To find your "stamp" you should walk backwards (in z-order) in your graph and find the first image your mouse position fall into.
Preferred sizes will not work, you should rely on size of "stamps" i think.
I found the answer myself. The key problem is that Swing doesn't want to layout a component unless that component has a proper parent. So, I changed my code to this:
parentComponent.add(nodeComponent);
// Set the node's size and validate it so it's laid out properly
nodeComponent.setBounds((int)realizer.getX(), (int)realizer.getY(), (int)realizer.getWidth(), (int)realizer.getHeight());
nodeComponent.validate();
// Now we can properly find the child component under our mouse
Component componentTop = nodeComponent.findComponentAt(relativeX, relativeY);
// Now remove it from the view
parentComponent.remove(nodeComponent);
And that works like a charm. You should be able to use a similar process to find child components in JLists or JTables (which also use this Renderer pattern).

Categories