SwingUtilities.convertPoint()返回负值

时间:2012-12-07 08:00:03

标签: java swing jpanel jlabel swingutilities

我在另一个项目中遇到了这个问题,这个项目复杂化了JPanels结构和许多代码。

在那里,我有一个以下代码段

Point point = label.getLocation();
Point point2 = SwingUtilities.convertPoint(label.getParent(), point, panel);

在动态选择标签和面板的地方,JLabel应该是JPanel的grand-grand -...- child。

那么为什么问题是在SwingUtilities.convertPoint()如果源和目标有子父关系的情况下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); } }); } } 可以返回负值?这有可能吗?

此代码演示了负坐标问题,但panel22不是标签的父级。

java.awt.Point[x=134,y=10]
java.awt.Point[x=134,y=-395]

所以输出是

label

UPD:基本上,我需要获得panel21相对于Point point = label.getLocation(); Point point2 = SwingUtilities.convertPoint(label.getParent(), point, panel21); 的位置。如何修改此行以实现它?

{{1}}

2 个答案:

答案 0 :(得分:7)

对我而言,这是正确的行为。想象一下如下。主面板包含位置x = 0 y = 100的子项。如果将主面板0,0转换为子节点,它将返回0,-100。 事实上,哪个组件是父组件并不重要。逻辑是添加(全部减去)所有translate()调用,当父项呈现子项时,这些调用将应用于图形。

答案 1 :(得分:4)

采取以下示例......

enter image description here

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));
            }
        });
    }        
}

生成(在我的系统上)以下输出

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]

如果我将label作为源组件传递,我会根据label与我试图转换为其坐标空间的组件之间的关系得到相对位置。如果我传递label的父节点,我会使用父坐标空间,这会产生不正确的结果

如果您查看labelbelow之间的关系,那么您会得到否定结果,因为label位于below的右上方