8

いくつかのJPanelを別のJPanelに入れました。そのレイアウトは、ボックスレイアウトとY軸です。すべてのパネルを配置した後、JPanelコンテナパネルから追加された各JPanelのY位置を取得する必要があります。しかし、それを取得しようとすると、各JPanelのY位置が常にゼロになります。JPanelコンテナJPanelから各JpanelのY位置を取得する方法を教えてください。

これは私がしたことです、

JPanel panelHolder = new JPanel(new BoxLayout(this, BoxLayout.Y_AXIS));
for(int i = 0; i< 10; i++){
   JPanel p = new JPanel(); 
   panelHolder.add(p);
}

int componentCount = panelHolder.getComponentCount();

for (int j = 0; i < componentCount ; j++) {

  Component c = pnlRowHolder.getComponent(i);
  JPanel p = (JPanel)c;
  System.out.println(p.getY());//I get zero for all
}
4

6 に答える 6

4

座標は親を基準にしています。たとえば、すべての子コンポーネントが親コンテナの上部に沿って追加され、yの位置が0になります(親に対して)。

親コンテナに空の境界線を追加してみてください。y位置が変化するはずです。

を使用しSwingUtilities.convertPointて、座標系間で変換できます

于 2012-09-25T20:13:03.830 に答える
3

位置を取得する前にフレームを梱包します。パックするまで、原点(0,0)からすべてが重なり合っているようです。

動作するコードは次のとおりです。

import java.awt.Component;
import java.awt.Dimension;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class TestBoxLayout {

    public static void main(String[] args) {
        JFrame frame = new JFrame();

        JPanel panelHolder = new JPanel();
        panelHolder.setLayout(new BoxLayout(panelHolder, BoxLayout.Y_AXIS));

        for (int i = 0; i < 10; i++) {
            JPanel p = new JPanel();
            p.setPreferredSize(new Dimension(100, 13)); //I set the height just to make sure.
            panelHolder.add(p);
        }
        frame.add(panelHolder);

        /**
         * Pack before you get the position.
         */
        frame.pack();

        int componentCount = panelHolder.getComponentCount();
        for (int j = 0; j < componentCount; j++) {
            Component c = panelHolder.getComponent(j);
            JPanel p = (JPanel) c;
            System.out.println(p.getY());//I get 0, 13, 26, 39, .....
        }

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

結果:

0
13
26
39
52
65
78
91
104
117

:BoxLayoutの署名はですBoxLayout(Container target, int axis)。これtargetは、レイアウトを設定するものです。このため、BoxLayoutを使用する場合は、常に最初にパネルを作成する必要があります。次にcomponent.setLayout()、ターゲットがすでに存在するように使用します。JPanelコンストラクターのthisは、ではなく他の何かを参照していpanelHolderました。この関数を作成したクラスものサブクラスであるContainerと思います。そのため、エラーは発生しませんでした。

于 2012-09-25T20:30:45.533 に答える
3

JPanelJFramescontentPaneに追加して、を使用してX座標とY座標を取得できるようにします。ただし、最初にすべてのコンポーネントを追加することをお勧めします。コンポーネントが追加されるとポイントが変わる可能性があるため、trashgodが言ったようにフレームインスタンスを呼び出すだけです。 。getX()get()pack()

私はデモンストレーションのために短いサンプルを作成しました:

import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Test {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new Test().createAndShowUI();
            }
        });
    }

    private void createAndShowUI() {
        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        initComponents(frame);
        
        frame.pack();//call pack 
        
        printPanelCompPoints(mainPanel);//produces correct coords
        
        frame.setVisible(true);
    }
    
    private JPanel mainPanel;

    private void initComponents(JFrame frame) {
        mainPanel = new JPanel(new BorderLayout());
        JPanel centerPanel = new JPanel();
        JPanel northPanel = new JPanel();
        JPanel southPanel = new JPanel();
        JPanel westPanel = new JPanel();
        JPanel eastPanel = new JPanel();

        centerPanel.add(new JLabel("CENTER"));
        northPanel.add(new JLabel("NORTH"));
        eastPanel.add(new JLabel("EAST"));
        southPanel.add(new JLabel("SOUTH"));
        westPanel.add(new JLabel("WEST"));

        mainPanel.add(centerPanel, BorderLayout.CENTER);
        mainPanel.add(northPanel, BorderLayout.NORTH);
        mainPanel.add(southPanel, BorderLayout.SOUTH);
        mainPanel.add(eastPanel, BorderLayout.EAST);
        mainPanel.add(westPanel, BorderLayout.WEST);

       frame.getContentPane().add(mainPanel);
    
       printPanelCompPoints(mainPanel);//produces all 0's
    }

    private void printPanelCompPoints(JPanel mainPanel) {
        for (int i = 0; i < mainPanel.getComponentCount(); i++) {
            System.out.println(mainPanel.getComponent(i).getX() + ", " + mainPanel.getComponent(i).getY());
        }
    }
}

ご覧のとおり、呼び出しはすべて0printPanelCompPoints(mainPanel);initComponents(JFrame frame)生成します(フレームに追加されているが、 `pack()は呼び出されていないため)。

0、0

0、0

0、0

0、0

0、0

ただし、sインスタンスを呼び出し たcreateAndShowUI()後、呼び出すと正しいco-odrinateが生成されます。pack()JFrameprintPanelCompPoints(mainPanel);

44、26

0、0

0、52

99、26

0、26

于 2012-09-25T20:06:06.583 に答える
2

JPanelの息子を含むJpanelの父親がいるとします。cxが父親に対する息子の座標xであり、cyが父親に対する息子の座標yである場合、次のようになります。

cx = son.getLocationOnScreen()。getX()-father.getLocationOnScreen()。getX()

cy = son.getLocationOnScreen()。getY()-father.getLocationOnScreen()。getY()

私は最も簡単な方法だと思います...

于 2014-04-02T15:15:23.120 に答える
1

JPanelコンテナJPanelから各JpanelのY位置を取得する方法を教えてください。

  • BoxLayoutXxxSize子を返す(Preferredこの場合)を受け入れる、

  • JPanel(0、0)を返しますこれは正しい値です

  • すべてから取得できるこの結果またはsimlairの結果LayoutManager、たとえば、built_in FlowLayoutfor JPanelPreferredSizeのみを受け入れる)は、同じ座標を返します(0, 0)

  • ただし、BorderLayout生成され10pixels(W、E、N、S領域の場合)、CENTER area一部の領域で使用される場合にのみ有効です。JComponent

  • JPanelであり、defualtContainerによって空JPanelになると、画面にゼロサイズが返されます。

  • JPanelJComponentコンストラクターにオーバーライドがある場合、またはコンストラクターでオーバーライドXxxSizeした場合、適切な座標を返すことができますJPanel

于 2012-09-25T20:42:49.373 に答える
0

多くの場合、問題は、メソッド全体が返された後にのみレイアウトまたは描画が行われることです。その場合は、 0getXgetY返します。

pack()フレームウィンドウ、またはdoLayout()作業validate()中のJPanelを呼び出すと役立つ場合があります。ただし、内部スケジューリングにはほとんど影響がないため、役に立たないことがよくあります 。http ://www.oracle.com/technetwork/java/painting-140037.html

この場合に役立つのは、XとYの位置が必要な部分をワーカースレッドに配置することです。

JPanel panelHolder = new JPanel(new BoxLayout(this, BoxLayout.Y_AXIS));
for(int i = 0; i< 10; i++){
    JPanel p = new JPanel(); 
    panelHolder.add(p);
}

int componentCount = panelHolder.getComponentCount();

SwingUtilities.invokeLater(new Runnable() {         
    @Override
    public void run() {
        for (int j = 0; i < componentCount; j++) {    
            Component c = pnlRowHolder.getComponent(i);
            JPanel p = (JPanel) c;
            System.out.println(p.getY());
        }
    }
});

このようにして、XとYの取得は、レイアウトが完了するまで延期されます。

于 2013-10-22T14:49:36.210 に答える