2014-02-26 27 views
1

我的主要問題是與下面的代碼段設立時JFrame的JFrame包()和requestFocus()方法是行不通的

  1. 爲什麼,如果我使用的面板不顯示pack()和如何使其工作?

  2. 爲什麼第一requestFocusInWindow()不工作的,什麼原則來使用它?

  3. 爲什麼如果我刪除setLayout(),默認佈局管理器JPanel不起作用?


public class SoundGUI extends KeyAdapter{ 

public static void main(String[] args) { 
    SoundGUI sGUI = new SoundGUI(); 
    sGUI.setUp(); 
} 
public void setUp() { 
    JFrame frame = new JFrame ("Key test"); 
    frame.setSize (1000, 300); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setVisible (true); 

    Panel p = new Panel(); 
    p.setLayout(new BorderLayout());//why this sentence is necessary FlowLayout doesn't fill the container but rather lets components size to their preferredSizes. 
    p.addKeyListener (this); 
    p.requestFocusInWindow();//it's useless here 
    //requestFocus only works on focusable components that are displayed. 
    MyDrawPanel dp = new MyDrawPanel(); 
    dp.setBackground(Color.darkGray); 

    JLabel test = new JLabel("a trial"); 
    JButton t = new JButton("b"); 
    dp.add(t); 
    dp.add (test); 
    p.add (dp);  
    frame.getContentPane().add(p); 
    p.requestFocusInWindow(); 
    //frame.pack();//why it doesn't work 
    //frame.setVisible(true); 
} 
class MyDrawPanel extends JPanel { 
    public void paintComponent (Graphics g) { 
     Graphics2D g2 = (Graphics2D) g; 
     g2.setColor(Color.white); 
     for (int i = 0; i < 1000; i += 42) { 
      g2.fill3DRect(i,100 ,20 ,80 ,true); 
     } 
     g2.setColor(Color.black); 
     for (int i = 21; i < 1000; i += 42) { 
      g2.fill3DRect(i,100 ,20 ,80 ,true); 
     } 
    } 
} 
} 
+0

爲什麼'requestFocus'工作時,如果你沒有真正添加面板的任何實際顯示在屏幕上,並提供給用戶...或者你只是不喜歡你的用戶... – MadProgrammer

+0

我明白了。謝謝。 – Tony

回答

5

建議:

  • 呼叫setVisible(true)調用pack()。有道理,不是嗎?
  • BorderLayout將告訴MyDrawPanel填充p容器,因爲組件是以默認方式添加的(意思是BorderLayout.CENTER),這就是BorderLayout的工作原理。
  • FlowLayout不會填充容器,而是讓組件大小爲其preferredSizes。
  • 請勿將Swing與AWT組件混合使用。即不使用面板,而是使用JPanel。
  • requestFocus僅適用於顯示的可調焦組件。
  • 更好地使用鍵綁定比KeyListeners。
  • 如果可能,最好避免設置任何大小。

基於新的代碼,你的問題是由於你調用setSize()。大多數佈局經理並不尊重這一點,而是偏好大小。如果你的繪圖JPanel需要這麼大,那就這樣做吧。例如嘗試:

class MyDrawPanel extends JPanel { 
    private static final int PREF_W = 1000; 
    private static final int PREF_H = 300; 

    public void paintComponent(Graphics g) { 
    super.paintComponent(g); //!! ******** don't forget this!!! ********* 
    Graphics2D g2 = (Graphics2D) g; 
    g2.setColor(Color.white); 
    for (int i = 0; i < 1000; i += 42) { 
     g2.fill3DRect(i, 100, 20, 80, true); 
    } 
    g2.setColor(Color.black); 
    for (int i = 21; i < 1000; i += 42) { 
     g2.fill3DRect(i, 100, 20, 80, true); 
    } 
    } 

    // the getPReferredSize will make this JPanel preferentially be this size 
    @Override 
    public Dimension getPreferredSize() { 
    return new Dimension(PREF_W, PREF_H); 
    } 
} 

另外請注意,要求重點確實如果組件是可聚焦工作:

JPanel p = new JPanel(); //!! This should be a JPanel, not a Panel 
    p.setFocusable(true); //!! This is needed 
    p.setLayout(new BorderLayout()); 
    p.addKeyListener(this); 
    p.requestFocusInWindow(); 

還要注意KeyListeners應該避免。改爲使用密鑰綁定。

+3

而使用輕不重的權重分量 – MadProgrammer

+2

關於這一點的延伸:Swing組件通常用J. –

+0

以爲你去接近它最終開始;) – MadProgrammer