问题
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 JFrame
s 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 JFrame
s 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
acceptingXxxSize
(Preferred
in this case) that returns its child,JPanel
returns (0, 0) this is correct valuethis or simlair result you can get from all
LayoutManager
, for example built_inFlowLayout
forJPanel
(accepting only thePreferredSiz
e), returns the same coordinates(0, 0)
excepting
BorderLayout
then is there generated10pixels
(for W, E, N, S areas), and valid only in the case thatCENTER area
is used for someJComponent
JPanel
isContainer
and by emptyJPanel
by defualt returns zero size on the screen,JPanel
can to returns proper coordinates if is there anyJComponent
or you overrideXxxSize
in theJPanel
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