Can the ComponentAt () work before the JComponent is drawn?

I am working on a GUI where JComponents are "stamped" on the screen. In other words, the actual components are not displayed, but the images of the components. This is a graph where the nodes of the graph represent custom Swing components - or rather, stamped images of Swing components.

Now I want to display tooltips for specific components in my nodes.

To do this, I create a JComponent that is identical to the one shown and using the mouse x and y values, I ask findComponentAt () for the correct component. This is not good. If I reuse JComponents for nodes it gets confused if I try to get a tooltip for a node that is different from the last one that was drawn. 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 () computation, but that still doesn't work. The root JComponent (JPanel) is sized as needed, but none of its children are sized yet.

Sample code for calculating tooltip:

// 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 is returned as the root JComponent no matter what x and y values ​​are passed.

So, is it possible to get Swing to calculate the size and position of the JComponents correctly without drawing them?

0


a source to share


2 answers


I found the answer myself. The main problem is that Swing doesn't want to link a component unless that component has a matching parent. So, I changed my code to this:

    parentComponent.add(nodeComponent);

    // Set the node size and validate it so it 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 it 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).

0


a source


You have graphics of your components that they must have in order to be able to draw correctly.

To find your "stamp", you have to go backward (in z-order) on your graph and find the first image that your mouse position hits.



The preferred sizes won't work, you have to rely on the size of the "stamps" I guess.

0


a source







All Articles