Получить местоположение компонента swing
Я поместил некоторые JPanels в другую JPanel, макет которой является макетом коробки и осью Y. После того, как я поместил все панели, мне нужно получить позицию Y каждого добавленного JPanel из панели контейнера JPanel. Но, когда я пытаюсь получить это, я всегда получаю ноль для позиции Y каждого JPanel. Пожалуйста, скажите мне, как получить позицию Y каждого Jpanel из контейнера JPanel JPanel.
вот что я сделал,
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 ответов
добавить JPanel
до JFrame
s contentPane таким образом, позволяя вам получить координаты X и Y, используя getX()
и get()
хотя я бы предложил сначала добавить все компоненты, так как точки могут измениться по мере добавления дополнительных компонентов, а затем, как сказал trashgod, просто позвоните pack()
на экземпляре frame.
я сделал короткий образец, чтобы продемонстрировать:
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
вызов экземпляра s printPanelCompPoints(mainPanel);
производит правильные co-odrinates:
44, 26
0, 0
0, 52
99, 26
0, 26
координаты относительно их родителя. В вашем примере все дочерние компоненты добавляются вдоль верхней части родительского контейнера, делая там y положение 0 (относительно их родителя).
попробуйте добавить пустую границу в родительский контейнер, вы должны увидеть изменение позиции y.
можно использовать SwingUtilities.convertPoint
для преобразования между системами координат
упакуйте рамку перед получением положения. Вроде все перекрывает друг друга, начиная с координат (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)
. The target
это то, что вы устанавливаете свой макет. По этой причине, если вы хотите использовать BoxLayout, вы всегда должны сначала создать панель. Тогда используйте component.setLayout()
так что цель уже существует. The this
в вашем конструкторе JPanel имел в виду что-то другое, а не panelHolder
. Я предполагаю, что класс, в котором вы создали эту функцию, также является подклассом Container
и именно поэтому вы не получили ошибку.
пожалуйста, скажите мне, как получить позицию Y каждого Jpanel из контейнера JPanel JPanel.
BoxLayout
приниматьXxxSize
(Preferred
в этом случае), который возвращает своего ребенка,JPanel
возвращает (0, 0) это правильное значениеэтот или simlair результат вы можете получить от всех
LayoutManager
, например встроенногоFlowLayout
наJPanel
(принимая толькоPreferredSiz
e), возвращает те же координаты(0, 0)
Кромы
BorderLayout
тогда генерируется10pixels
(для областей W, E, N, S) и действительны только в том случае, еслиCENTER area
используется для некоторыхJComponent
JPanel
isContainer
и пустойJPanel
по умолчанию возвращает нулевой размер на экране,JPanel
может возвращает правильные координаты, если есть какие-либоJComponent
или вы переопределяетеXxxSize
наJPanel
конструктор
Предположим, у вас есть отец Jpanel, который содержит сына JPanel. Если cx-координата X сына по отношению к отцу, а cy-координата y сына по отношению к отцу, то:
cx = сын.getLocationOnScreen().getX()-отец.getLocationOnScreen().getX()
cy = сын.getLocationOnScreen().Гети()-отец.getLocationOnScreen().Гети ()
Я думаю, это самый простой способ...
проблема часто заключается в том, что макет или чертеж выполняются только после возврата всего метода. В таком случае ...--1--> и getY
возвращает 0.
это может помочь, чтобы вызвать 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 будет отложено до тех пор, пока макет не будет сделан.