2012-09-25 51 views
6

我已經將一些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 
} 
+9

嘗試檢查_after_ 'validate()'或'pack()';另外,編輯你的問題,包括一個[sscce](http://sscce.org/),它們顯示你的方法。 – trashgod

回答

3

添加您JPanelJFrame小號的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,(因爲他們已經加入到框架,但'包()沒有被調用) 。

0,0

0,0

0,0

0,0

0,0

然而在 createAndShowUI()

主叫pack()後在JFrame s insta NCE調用printPanelCompPoints(mainPanel);產生正確的共odrinates:

44,26

0,0

0,52

99,26

0,26

4

座標是相對於他們的父母。在你的例子中,所有的子組件都沿着父容器的頂部添加,使得位置0(相對於它們的父代)。

嘗試添加一個空的邊框到父容器,你應該看到y位置的變化。

可以使用SwingUtilities.convertPoint轉換之間的座標系

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()以便目標已經存在。您的JPanel構造函數中的this指的是其他內容,而不是panelHolder。我猜你創建這個函數的類也是Container的子類,這就是爲什麼你沒有得到一個錯誤。

+0

+1如此接近真,[但默認isn9t有理由設置XxxSize](http://stackoverflow.com/questions/7229226/should-i-avoid-the-use-of-setpreferredmaximumminimumsize-methods- in-java-swi) – mKorbel

+0

@mKorbel通常,我讓佈局管理器組織首選大小的組件。我只使用'setPreferredSize'來測試一個不同的數字。沒有這個,我得到了'0,10,20 ......'這仍然是正確的。 – davidXYZ

+0

hehehe ...請re_read問題:-) – mKorbel

1

請告訴我如何從JPanel容器JPanel獲取每個Jpanel的Y位置。

  • BoxLayout接受XxxSizePreferred在這種情況下),返回其子,

  • JPanel返回(0,0),這是正確的值

  • 這樣或simlair結果可以得到全部LayoutManager,例如built_in FlowLayoutJPanel(僅接受PreferredSiz e),返回相同的座標(0, 0)

  • 除外BorderLayout則存在僅在該CENTER area用於一些JComponent

  • JPanel的情況下產生的10pixels(爲W,E,N,S的區域),和有效是Container和由空JPanel如果有任何JComponent或者您在覆蓋XxxSize由defualt返回零尺寸在屏幕上,

  • JPanel可以以適當的回報座標3210的構造函數

0

問題往往在於整個方法返回後才完成佈局或繪圖。在這種情況下,getXgetY返回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將被推遲到佈局完成。

0

假設您的Jpanel父親包含JPanel兒子。如果cx是兒子相對於父親的座標x,cy是兒子相對於父親的座標y,則:

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

CY = son.getLocationOnScreen()的getY() - father.getLocationOnScreen()的getY()

我認爲這是最簡單的方法...