8

我已将一些 JPanel 放入另一个 JPanel,其布局为 Box Layout 和 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(),使目标已经存在。您的thisJPanel 构造函数中的 是指其他东西,而不是panelHolder. 我猜你创建这个函数的类也是它的子类,Container这就是你没有得到错误的原因。

于 2012-09-25T20:30:45.533 回答
3

将您添加JPanelJFrames contentPane从而允许您使用 X 和 Y 坐标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());
        }
    }
}

如您所见,调用printPanelCompPoints(mainPanel);产生initComponents(JFrame frame)所有 0,(因为它们已添加到框架中但尚未调用 `pack())。

0, 0

0, 0

0, 0

0, 0

0, 0

但是在调用createAndShowUI()s实例之后调用 会产生正确的 co-odrinates: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 位置。

  • BoxLayout接受XxxSizePreferred在这种情况下)返回它的孩子,

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

  • 您可以从 all 中获得 this 或 simlair 结果LayoutManager,例如 built_in FlowLayoutfor JPanel(仅接受PreferredSize),返回相同的坐标(0, 0)

  • 除了BorderLayout那里生成10pixels(用于 W、E、N、S 区域),并且仅在CENTER area用于某些情况下有效JComponent

  • JPanelis Containerand by empty JPanelby defualt 在屏幕上返回零大小,

  • JPanel可以返回正确的坐标(如果有的话)或者你在构造函数中JComponent重写XxxSizeJPanel

于 2012-09-25T20:42:49.373 回答
0

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

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 回答