获取挥杆组件的位置

时间:2012-09-25 19:31:20

标签: java swing jpanel layout-manager

我已将一些JPanel放入另一个JPanel,其布局是Box Layout和Y-Axis。 在我放置所有面板后,我需要从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
}

6 个答案:

答案 0 :(得分:4)

坐标是相对于父母的。在您的示例中,所有子组件都是沿父容器的顶部添加的,使得位置0(相对于其父级)。

尝试向父容器添加空边框,您应该看到y位置更改。

您可以使用SwingUtilities.convertPoint在坐标系之间进行转换

答案 1 :(得分:3)

JPanel添加到JFrame contentPane ,这样您就可以使用getX()get()来获取X和Y坐标我建议先添加所有组件,因为随着更多组件的添加,这些点可能会发生变化,然后就像垃圾邮件说只需在框架实例上调用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());
        }
    }
}

正如你所看到的,在printPanelCompPoints(mainPanel);中调用initComponents(JFrame frame)会产生全0,(因为它们已被添加到帧中,但尚未调用`pack())。

  

0,0

     

0,0

     

0,0

     

0,0

     

0,0

然而在createAndShowUI()调用pack() JFrame之后调用printPanelCompPoints(mainPanel);的实例会调用{{1}}产生正确的共同点:

  44,26

     

0,0

     

0,52

     

99,26

     

0,26

答案 2 :(得分: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的子类,这就是你没有得到错误的原因。

答案 3 :(得分:1)

  

请告诉我如何从JPanel容器JPanel获取每个Jpanel的Y位置。

  • BoxLayout接受返回其子女的XxxSize(本例中为Preferred

  • JPanel返回(0,0)这是正确的值

  • 您可以从所有LayoutManager获取此simlair结果,例如FlowLayout的built_in JPanel(仅接受PreferredSiz e),返回相同的结果坐标(0, 0)

  • 除了BorderLayout之外,还会生成10pixels(针对W,E,N,S区域),并且只有在CENTER area用于某些{的情况下才有效{1}}

  • JComponentJPanel,而空Container为defualt,屏幕返回零尺寸,

  • JPanel可以返回正确的坐标,如果有任何JPanel或您在JComponent构造函数中覆盖XxxSize

答案 4 :(得分:1)

假设你有一个包含JPanel子的Jpanel父亲。如果cx是儿子相对于父亲的坐标x而cy是儿子相对于父亲的坐标y,那么:

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

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

我认为这是最简单的方法......

答案 5 :(得分:0)

问题通常是布局或绘图仅在返回整个方法后完成。在这种情况下,getXgetY会返回0。

在框架窗口上调用pack()或在您正在处理的JPanel上调用doLayout()validate()可能会有所帮助。但通常它没有帮助,因为你对内部调度几乎没有影响: 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,直到布局完成。