Get location of a swing component

前端 未结 6 1231
野的像风
野的像风 2021-01-18 03:19

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

相关标签:
6条回答
  • 2021-01-18 03:55

    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.

    0 讨论(0)
  • 2021-01-18 04:01

    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

    0 讨论(0)
  • 2021-01-18 04:08

    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

    0 讨论(0)
  • 2021-01-18 04:15

    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.

    0 讨论(0)
  • 2021-01-18 04:17

    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

    0 讨论(0)
  • 2021-01-18 04:17

    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...

    0 讨论(0)
提交回复
热议问题