Get location of a swing component

☆樱花仙子☆ 提交于 2019-12-01 17:14:41

问题


I have put some JPanels into another JPanel which its' layout is Box Layout and Y-Axis. After I have put all the panels I need to get the Y position of each added JPanel in from the JPanel container panel. But, when I try to get that I always get zero for Y position of each JPanel. Please tell me how to get the Y position of each Jpanel from the JPanel container JPanel.

This is what I have done,

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
}

回答1:


Add your JPanel to the JFrames contentPane thus allowing you to get the X and Y co ordinates using getX() and get() though I'd suggest adding all components first, as the points may change as more components are added and then as trashgod said simply call pack() on the frame instance.

I did a short sample to demonstrate:

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

As you can see calling printPanelCompPoints(mainPanel); in initComponents(JFrame frame) produces all 0's, (as they have been added to the frame but `pack() has not been called).

0, 0

0, 0

0, 0

0, 0

0, 0

however in the createAndShowUI() after calling pack() on the JFrames instance calling printPanelCompPoints(mainPanel); produces the correct co-odrinates:

44, 26

0, 0

0, 52

99, 26

0, 26




回答2:


Coordinates are relative to their parent. In your exemple, all the child components are being added along the top of the parent container, making there y position 0 (relative to their parent).

Try adding an empty border to the parent container, you should see the y position change.

You can use the SwingUtilities.convertPoint to convert between coordinate systems




回答3:


Pack the frame before getting position. It seems everything overlaps each other starting at origin (0,0) until you pack.

Here's a working code:

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

Result:

0
13
26
39
52
65
78
91
104
117

Note: The signature for BoxLayout is BoxLayout(Container target, int axis). The target is the stuff you are setting your layout to. For this reason, if you want use a BoxLayout, you should always create the panel first. Then use component.setLayout() so that the target already exists. The this in your JPanel constructor was referring to something else, not panelHolder. I guess the class you created this function in is also a subclass of Container and that is why you didn't get an error.




回答4:


Please tell me how to get the Y position of each Jpanel from the JPanel container JPanel.

  • BoxLayout accepting XxxSize (Preferred in this case) that returns its child,

  • JPanel returns (0, 0) this is correct value

  • this or simlair result you can get from all LayoutManager, for example built_in FlowLayout for JPanel (accepting only the PreferredSize), returns the same coordinates (0, 0)

  • excepting BorderLayout then is there generated 10pixels(for W, E, N, S areas), and valid only in the case that CENTER area is used for some JComponent

  • JPanel is Container and by empty JPanel by defualt returns zero size on the screen,

  • JPanel can to returns proper coordinates if is there any JComponent or you override XxxSize in the JPanel constructor




回答5:


Suppose you have Jpanel father that contains a JPanel son. If cx is the coordinate x of the son with respect to the father and cy is the coordinate y of the son with respect to the father, then:

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

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

I think is the easiest way...




回答6:


The problem is often that the layout or the drawing is done only after the whole method returned. In that case, getX and getY return 0.

It may help to call pack() on the frame window, or doLayout() or validate() on the JPanel you are working on. But often it doesn't help, because you have little influence on the internal scheduling: http://www.oracle.com/technetwork/java/painting-140037.html

What does help me in this case is to put the part where I need the X and Y location into a worker thread:

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

This way getting the X and Y will be postponed until the layout is done.



来源:https://stackoverflow.com/questions/12589824/get-location-of-a-swing-component

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!