2012-06-27 42 views
0

我試圖做一個盒子在具有「用戶」,輸入用戶名文本字段和按鈕「符號」的標籤搖擺。這是我的代碼搖擺的getHeight()值更改爲0〜16

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 
import java.io.*; 
import java.util.*; 

public class Engine 
{ 
    JFrame frame; 
    public void go() 
    { 
     setUpGui(); 
     userNameScreen(); 
    } 
    public void setUpGui() 
    { 
     frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 
    public void userNameScreen() 
    { 
     JPanel background = new JPanel(); 
      frame.getContentPane().add(background); 
     JLabel labelUserName = new JLabel("User:"); 
      background.add(labelUserName); 
      System.out.println(labelUserName.getHeight()); // 0 
     JTextField textFieldUserName = new JTextField(); 
      System.out.println(labelUserName.getHeight()); // 16 
      textFieldUserName.setPreferredSize(new Dimension(110,labelUserName.getHeight())); 
      background.add(textFieldUserName); 
     JButton buttonSignIn = new JButton("Sign In"); 
      background.add(buttonSignIn); 
     /* 
     background.add(labelUserName); 
     background.add(textFieldUserName); 
     background.add(buttonSignIn); 
     frame.getContentPane().add(background); 
     */ 
     frame.pack(); 
    } 
} 

我的驅動程序類只是創建引擎的一個實例,然後運行方法go()。
我讀了Swing組件不具有高度/寬度的屬性,直到它們被添加(因爲這是佈局管理器來決定他們的房間有多少),因此它是有道理的,在方法userNameScreen(),將在*結尾的所有組件*(這裏註釋掉)使得textFieldUserName變量沒有高度。
但是,您可以在同一方法userNameScreen()看​​,我把它做

System.out.println(labelUserName.getHeight()); 

兩次。第一次,它是0.第二次,它是16.我不明白爲什麼第一次,它會將它註冊爲0.它已經被添加到面板中(在之前的行中),並且沒有在第一個println()和下一個println()之間似乎沒有任何東西會改變它的高度。那麼爲什麼第一個值爲0,爲什麼它幾乎立即變爲16?

*我應該注意到,當我在最後註釋掉所有的東西都說加入,還包括刪除/註釋掉所有代碼做過的相同的命令。

+1

無關,但很重要:不使用setXXSize _ever_至於原因,看http://stackoverflow.com/questions/7229226/should-i-avoid-在使用-的-setpreferredmaximumminimumsize的方法,在-Java的SWI/7229519#7229519 – kleopatra

回答

2

這是從沒有創造/在美國東部時間修改您的Swing組件的副作用。現在美國東部時間正在忙着做佈局,而你正在另一個線程中添加組件。

你的主要方法應該是這樣的:

public static void main(String[] args) { 
    EventQueue.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
      new Engine().go(); 
     } 
    }); 
} 
+0

他並沒有創造另一個線程,yru說,EDT是忙着做佈局。美國東部時間應該忙於佈局。 – vedant1811

+0

@ vedant1811主線程(由JVM創建)不是EDT。 EDT在您自動創建組件時由Swing/AWT創建,因此最終(至少)有兩個線程。 –

+0

@walterLann我明白了。那麼使用inovkeLater會導致所有東西在EDT上運行? – vedant1811

1

我不知道爲什麼發生這種情況,但可能是因爲也許在後臺線程和可能尚未更新,直到下一個語句添加成分被稱爲和少數的毫秒後它的更新並顯示,當你再次調用它。