4

複雑なJPanels構造と多くのコードを持つ別のプロジェクトでこの問題に直面しています。

そこには次のスニペットがあります

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

ラベルとパネルが動的に選択され、JLabel が JPanel の孫孫であると想定されている場所。

SwingUtilities.convertPoint()では、ソースと宛先が親子関係にある場合、どのような場合に負の値を返すことができるのでしょうか? これはまったく可能ですか?

このコードは負の座標の問題を示していますが、panel22 はラベルの親ではありません。

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

したがって、出力は

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

UPD: 基本的に、 のlabel相対位置を取得する必要がありpanel21ます。この行を変更して達成するにはどうすればよいですか?

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

2 に答える 2

7

私にとっては正しい行動です。次を想像してみてください。メイン パネルには、位置 x=0 y=100 の子が含まれています。メイン パネルの 0,0 ポイントを子に変換すると、0, -100 が返されます。実際、どのコンポーネントがどのコンポーネントの親であるかは問題ではありません。ロジックは、親が子をレンダリングするときにグラフィックスに適用されるすべての translate() 呼び出しを加算 (すべて減算) することです。

于 2012-12-07T08:14:45.720 に答える
4

次の例を見てください...

ここに画像の説明を入力

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代わりに親の座標空間を使用しているため、誤った結果が生成されます。

labelとの関係を見ると、上と右にあるようにbelow、否定的な結果が得られることは理にかなっています。labelbelow

于 2012-12-07T08:45:32.333 に答える