Получить местоположение компонента swing

Я поместил некоторые JPanels в другую JPanel, макет которой является макетом коробки и осью Y. После того, как я поместил все панели, мне нужно получить позицию Y каждого добавленного JPanel из панели контейнера JPanel. Но, когда я пытаюсь получить это, я всегда получаю ноль для позиции Y каждого JPanel. Пожалуйста, скажите мне, как получить позицию Y каждого Jpanel из контейнера JPanel JPanel.

вот что я сделал,

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
}

6 ответов


добавить JPanel до JFrames contentPane таким образом, позволяя вам получить координаты X и Y, используя getX() и get() хотя я бы предложил сначала добавить все компоненты, так как точки могут измениться по мере добавления дополнительных компонентов, а затем, как сказал trashgod, просто позвоните pack() на экземпляре frame.

я сделал короткий образец, чтобы продемонстрировать:

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

как вы можете видеть вызов printPanelCompPoints(mainPanel); на initComponents(JFrame frame) производит все 0, (как они были добавлены к кадру, но ' pack () не был вызван).

0, 0

0, 0

0, 0

0, 0

0, 0

на createAndShowUI() после вызова pack() на JFrameвызов экземпляра s printPanelCompPoints(mainPanel); производит правильные co-odrinates:

44, 26

0, 0

0, 52

99, 26

0, 26


координаты относительно их родителя. В вашем примере все дочерние компоненты добавляются вдоль верхней части родительского контейнера, делая там y положение 0 (относительно их родителя).

попробуйте добавить пустую границу в родительский контейнер, вы должны увидеть изменение позиции y.

можно использовать SwingUtilities.convertPoint для преобразования между системами координат


упакуйте рамку перед получением положения. Вроде все перекрывает друг друга, начиная с координат (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). The target это то, что вы устанавливаете свой макет. По этой причине, если вы хотите использовать BoxLayout, вы всегда должны сначала создать панель. Тогда используйте component.setLayout() так что цель уже существует. The this в вашем конструкторе JPanel имел в виду что-то другое, а не panelHolder. Я предполагаю, что класс, в котором вы создали эту функцию, также является подклассом Container и именно поэтому вы не получили ошибку.


пожалуйста, скажите мне, как получить позицию Y каждого Jpanel из контейнера JPanel JPanel.

  • BoxLayout принимать XxxSize (Preferred в этом случае), который возвращает своего ребенка,

  • JPanel возвращает (0, 0) это правильное значение

  • этот или simlair результат вы можете получить от всех LayoutManager, например встроенного FlowLayout на JPanel (принимая только PreferredSize), возвращает те же координаты (0, 0)

  • Кромы BorderLayout тогда генерируется 10pixels(для областей W, E, N, S) и действительны только в том случае, если CENTER area используется для некоторых JComponent

  • JPanel is Container и пустой JPanel по умолчанию возвращает нулевой размер на экране,

  • JPanel может возвращает правильные координаты, если есть какие-либо JComponent или вы переопределяете XxxSize на JPanel конструктор


Предположим, у вас есть отец Jpanel, который содержит сына JPanel. Если cx-координата X сына по отношению к отцу, а cy-координата y сына по отношению к отцу, то:

cx = сын.getLocationOnScreen().getX()-отец.getLocationOnScreen().getX()

cy = сын.getLocationOnScreen().Гети()-отец.getLocationOnScreen().Гети ()

Я думаю, это самый простой способ...


проблема часто заключается в том, что макет или чертеж выполняются только после возврата всего метода. В таком случае ...--1--> и getY возвращает 0.

это может помочь, чтобы вызвать 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 будет отложено до тех пор, пока макет не будет сделан.