2012-10-24 103 views
2

我在理解應用程序的行爲時遇到了問題。我想創建一個簡單的窗口(分別爲250px750px寬度),創建一個簡單的窗口(1000x700px)。我嘗試下面的代碼:Java Swing:寬度問題

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.FlowLayout; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class Example extends JFrame 
{ 
    private static final long serialVersionUID = 1L; 

    public Example() 
    { 
     this.setSize(1000, 700); 
     this.setTitle("Example"); 
     this.setResizable(false); 
     this.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); 

     JPanel navigation_panel_wrap = new JPanel(); 
     JPanel content_panel_wrap = new JPanel(); 
     navigation_panel_wrap.setPreferredSize(new Dimension(250, 700)); 
     content_panel_wrap.setPreferredSize(new Dimension(750, 700)); 
     content_panel_wrap.setBackground(Color.green); 
     navigation_panel_wrap.setBackground(Color.red); 
     this.getContentPane().add(navigation_panel_wrap); 
     this.getContentPane().add(content_panel_wrap); 
    } 

    public static void main(String[] args) 
    { 
     Example example = new Example(); 
     example.setVisible(true); 
    } 
} 

正如你可以看到我手動設置的佈局管理器JFrameFlowLayout而不是BorderLayout零水平和垂直間距)。當然,我可以使用BorderLayout並使用add()方法與BorderLayout.EASTBorderLayout.WEST參數,但我想了解FlowLayout有什麼問題。 當我運行我的應用程序,我得到以下(無綠色JPanel):enter image description here

如果我減少的寬度,例如,content_panel_wrap和利用它744px代替750px,一切正常。 enter image description here 所以問題是 - 這些奇怪的6像素是什麼?我不確定這個值對於所有的操作系​​統是不變的,所以我想了解它的起源。

+2

看到這個[Q&A](http://stackoverflow.com/q/7229226/230513)。 – trashgod

+0

非常感謝,非常有幫助的鏈接。 –

回答

3

至於你的代碼問題(+ 1到@Reimeus)調用pack()是解決方案。 按照文檔:

此窗口的大小,以適合的優選尺寸和佈局其子組件的 。如果窗口和/或其所有者尚未顯示,則在計算 首選大小之前,兩者都可顯示。該窗口將在計算preferredSize 後進行驗證。

提示:

  • 不要不必要地延長JFrame
  • 使用創建和更改UI組件時Event Dispatch Thread

    SwingUtilities.invokeLater(new Runnable() { 
        @Override 
        public void run() { 
         // create UI components etc here 
        } 
        }); 
    
  • 不要調用setPreferredSize()而控制組件的getPrefferedSize()
  • 不要在JFrame上調用setSize(...),而是在將其設置爲可見之前先調用JFrame#pack()
  • 不要忘記打電話JFrame#defaultCloseOperation(..)或當JFrame關閉時,您的初始/ EDT線程不會被終止。

這裏是結合我的意見,你的代碼的例子:

enter image description here

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.FlowLayout; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

public class Example { 

    private final JFrame frame; 

    public Example() { 
     frame = new JFrame(); 
     frame.setTitle("Example"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//app exited when frame closes 
     frame.setResizable(false); 
     frame.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); 

     JPanel navigation_panel_wrap = new JPanel() { 
      @Override 
      public Dimension getPreferredSize() { 
       return new Dimension(250, 700); 
      } 
     }; 
     JPanel content_panel_wrap = new JPanel() { 
      @Override 
      public Dimension getPreferredSize() { 
       return new Dimension(750, 700); 
      } 
     }; 

     content_panel_wrap.setBackground(Color.green); 
     navigation_panel_wrap.setBackground(Color.red); 

     frame.add(navigation_panel_wrap); 
     frame.add(content_panel_wrap); 
     //pack frame (size components to preferred size) 
     frame.pack(); 
     frame.setVisible(true);//make frame visible 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new Example(); 
      } 
     }); 
    } 
} 
+1

感謝您的詳細解答! 除了兩件事之外,一切都很清楚: 1. _Dont不必要地擴展JFrame._ 我不應該擴展所有Swing類,如JLabel,JPanel等或僅僅是JFrame?做這件事的原因是什麼? 2.使用setPreferredSize()重寫getPrefferedSize()的優點是什麼? –

+1

@ user1600356 +1其樂無窮。至於'JFrame'的擴展問題:1)你只擴展類來添加功能2)一旦你擴展了'JFrame',你不能擴展你實際需要的另一個類。至於你的問題:*使用setPreferredSize()重載g​​etPrefferedSize()的好處是什麼?*請參閱此鏈接:[我應該避免在Java Swing中使用set \ [Preferred | Maximum | Minimum \] Size方法嗎?] (http://stackoverflow.com/q/7229226/1133011) –

4

FlowLayout沒有問題,但您需要致電pack()以確定所有組件的大小。