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);
For me it's correct behaviour. Imagine following. Main panel contains a child with location x=0 y=100. If you convert the main panel 0,0 point to the child it returns us 0, -100. In fact it doesn't matter which component is parent of which. The logic is to add (all subtract) all translate() calls which are applied to graphics when parent renders child.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With