tags:

views:

121

answers:

2

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?

A: 

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.

eugener
The problem isn't with finding the correct node. I have that. The problem is getting the child component within the node. I want different tooltips in the same node depending on whether the mouse is over a label or image.
David Irwin
A: 

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).

David Irwin