SwingUtilities.convertPoint() returns negative values
java, jlabel, jpanel, swing, swingutilities
Solution
Take the following example...
public class TestLocation01 {
public static void main(String[] args) {
new TestLocation01();
}
public TestLocation01() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JPanel outter = new JPanel(new BorderLayout());
outter.setBorder(new CompoundBorder(new LineBorder(Color.RED), new EmptyBorder(10, 10, 10, 10)));
JPanel inner = new JPanel(new GridBagLayout());
inner.setBorder(new CompoundBorder(new LineBorder(Color.BLUE), new EmptyBorder(10, 10, 10, 10)));
JLabel label = new JLabel("Testing");
inner.add(label);
outter.add(inner);
JLabel below = new JLabel("Below");
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(outter);
frame.add(below, BorderLayout.SOUTH);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
System.out.println("lable.location: " + label.getLocation());
System.out.println("label to inner: " + SwingUtilities.convertPoint(label, new Point(0, 0), inner));
System.out.println("label to outter: " + SwingUtilities.convertPoint(label, new Point(0, 0), outter));
System.out.println("label.parent to inner: " + SwingUtilities.convertPoint(label.getParent(), new Point(0, 0), inner));
System.out.println("label.parent to outter: " + SwingUtilities.convertPoint(label.getParent(), new Point(0, 0), outter));
System.out.println("label to frame: " + SwingUtilities.convertPoint(label, new Point(0, 0), frame));
System.out.println("label.getParent to frame: " + SwingUtilities.convertPoint(label.getParent(), new Point(0, 0), frame));
System.out.println("outter to label: " + SwingUtilities.convertPoint(outter, new Point(0, 0), label));
System.out.println("label to below: " + SwingUtilities.convertPoint(label, new Point(0, 0), below));
System.out.println("below to label: " + SwingUtilities.convertPoint(below, new Point(0, 0), label));
}
});
}
}
Which generates (on my system) the following output
lable.location: java.awt.Point[x=65,y=62]
label to inner: java.awt.Point[x=65,y=62]
label to outter: java.awt.Point[x=76,y=73]
label.parent to inner: java.awt.Point[x=0,y=0]
label.parent to outter: java.awt.Point[x=11,y=11]
label to frame: java.awt.Point[x=76,y=95]
label.getParent to frame: java.awt.Point[x=11,y=33]
outter to label: java.awt.Point[x=-76,y=-73]
label to below: java.awt.Point[x=76,y=-89]
below to label: java.awt.Point[x=-76,y=89]
If I pass the `label` as the source component, I get relative positions based upon the relationship between the `label` and the component whose coordinate space I'm trying to convert to. If I pass the `label`'s parent, I'm using the parent coordinate space instead, which is bound to produce an incorrect result
If you look at the relationship between `label` and `below` it makes sense to that you would get negative results, as `label` is above and to the right of `below`
Problem
I am facing this issue in another project which has complicated JPanels structure and much code. In there I have a following snippet ``` Point point = label.getLocation(); Point point2 = SwingUtilities.convertPoint(label.getParent(), point, panel); ``` in where label and panel are selected dynamically and JLabel is supposed to be grand-grand-...-child of JPanel. So why question is in what case `SwingUtilities.convertPoint()` can return negative values if source and destination have child-parent relation? Is this possible at all? This code demonstrated negative coordinates issue, but there panel22 is not parent of label. ``` import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Point; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.SwingUtilities; public class NegativeLocation { public static void main(String[] args) { new NegativeLocation(); } public NegativeLocation() { EventQueue.invokeLater(new Runnable() { @Override public void run() { JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); JPanel panel1 = new JPanel() { @Override public Dimension getPreferredSize() { return new Dimension(600, 400); } }; JPanel panel21 = new JPanel() { @Override public Dimension getPreferredSize() { return new Dimension(300, 400); } }; panel1.add(panel21); JPanel panel22 = new JPanel() { @Override public Dimension getPreferredSize() { return new Dimension(300, 400); } }; panel1.add(panel22); JPanel panel3 = new JPanel() { @Override public Dimension getPreferredSize() { return new Dimension(300, 400); } }; panel21.add(panel3); JLabel label = new JLabel("Label"); panel3.add(label); frame.getContentPane().add(panel1); frame.setPreferredSize(new Dimension(600, 400)); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); Point point = label.getLocation(); Point point2 = SwingUtilities.convertPoint(label.getParent(), point, panel21); Point point3 = SwingUtilities.convertPoint(label.getParent(), point, panel22); System.out.println(point2); System.out.println(point3); } }); } } ``` So the output is ``` java.awt.Point[x=134,y=10] java.awt.Point[x=134,y=-395] ``` UPD: Basically, I need to get location of `label` relative to `panel21`. How can I modify this line to achive it? ``` Point point = label.getLocation(); Point point2 = SwingUtilities.convertPoint(label.getParent(), point, panel21); ```