2009-10-20 129 views
3

我創建了一個帶有JPanel的窗體,裏面有一些圖形和一些按鈕來控制事物。出於某種原因,我必須指定JPanel的寬度比要放入其中的實際圖形小10px,並且低30px。什麼導致這個問題?JPanel周圍不需要的邊框

這是代碼:

public class Window { 
public Sheepness sheepness; 

public ButtonPanel buttonPanel; 
public PaintPanel paintPanel; 
public JFrame frame; 

public Window(Sheepness sheepness) { 
    this.sheepness = sheepness; 

    frame = new JFrame("Sheepness simulation"); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    //frame.setSize(width, height); 

    BorderLayout frameLayout = new BorderLayout(); 
    JPanel background = new JPanel(frameLayout); 
    background.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); 

    buttonPanel = new ButtonPanel(this); 
    background.add(BorderLayout.SOUTH, buttonPanel.buttonBox); 

    paintPanel = new PaintPanel(this); 
    paintPanel.setPreferredSize(new Dimension(320, 240)); 
    background.add(BorderLayout.CENTER, paintPanel); 

    frame.getContentPane().add(background); 
    frame.pack(); 
    frame.setResizable(false); 
    frame.setVisible(true); 
} 
} 

public class PaintPanel extends JPanel { 
public Window window; 

public PaintPanel(Window window) { 
    this.window = window; 
} 

@Override 
public void paintComponent(Graphics g) { 
    g.setColor(Color.blue); 
    g.fillRect(0, 0, 320, 240); 
} 
}

截圖爲320×240一個首選大小:

Can't find source image http://www.cmbi.ru.nl/~estens/Sheepness/Sheepness_simulation_border.png

您可以看到320 x 240 fillRect未完全填充JPanel,仍​​保留10 px寬度和30 px高度的邊框。

截圖與310 X 210使用preferredSize:

Can't find source image http://www.cmbi.ru.nl/~estens/Sheepness/Sheepness_simulation_noBorder.png

現在它正好適合320 x 240 fillRect!

任何想法?

+0

嘗試添加'Border'('BorderFactory.createLineBorder(Color.RED,1)')圍繞'paintPanel'這樣就可以排除用'buttonPanel'相互作用。 – 2009-10-20 12:19:11

+0

我用setPreferredSize:參數:寬度:640,高度:480,在setPreferredSize和setSize:Width:640,Height:480,frame.pack:Width:650,Height:510之後設置它後,檢查了JPanel的大小。我想它與包裝一切的算法有關。不過,尺寸增加並不奇怪嗎?有沒有辦法告訴事情停止觸摸我的組件的大小,只是他們的路線?我認爲這應該是setPreferredSize,但我猜這不符合它的要求。 – FinalArt2005 2009-10-20 13:21:18

+0

順便說一句,添加邊框顯示與buttonPanel沒有任何交互,因爲它顯示JPanel與按鈕很好地排列在一起,但正如您可以從之前的註釋中讀取的那樣,JPanel本身在打包後尺寸錯誤。 – FinalArt2005 2009-10-21 17:26:34

回答

3

不同的佈局管理器使用不同的規則來計算實際的託管控件大小,也就是說,只有當您調用'setPreferredSize()'時,才能期望面板具有特定大小。

隨時在所有特定情況下檢查所有目標佈局管理器的javadoc以獲取有關已使用算法的更多詳細信息。

另請注意,您可以避免使用佈局管理器,並通過'setBounds()'方法絕對定義所有尺寸。

0

我想你的屏幕截圖上的標籤錯了。

如果指定

g.fillRect(0, 0, 310, 210); 
在PaintPanel

paintPanel.setPreferredSize(new Dimension(320, 240)); 
在窗口

。你得到了第一個截圖顯示的內容。這是有道理的,因爲矩形的寬度減少了10px,高度減少了30px。

如果你爲兩者設置相同的寬度/高度; 310,210,藍色的矩形顯然會「填充」PaintPanel。

+0

不,它是向後的:它將fillRect設置爲0,0,320,240,並將preferredSize設置爲310,210,您將獲得填充的屏幕截圖,同樣的尺寸可以獲得邊框,這正是我的問題所在。 – FinalArt2005 2009-10-20 12:28:01

1

這裏是一個自包含的測試用例,根據您的代碼:

 
import java.awt.*; 
import javax.swing.*; 

public class Test { 

public PaintPanel paintPanel; 
public JFrame frame; 

public Test() { 
    frame = new JFrame("Sheepness simulation"); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    //frame.setSize(width, height); 

    BorderLayout frameLayout = new BorderLayout(); 
    JPanel background = new JPanel(frameLayout); 
    background.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); 

    paintPanel = new PaintPanel(this); 
    paintPanel.setPreferredSize(new Dimension(320, 240)); 
    background.add(BorderLayout.CENTER, paintPanel); 

    frame.getContentPane().add(background); 
    frame.pack(); 
    frame.setResizable(false); 
    frame.setVisible(true); 
} 

    public static class PaintPanel extends JPanel { 
    public Test window; 

    public PaintPanel(Test window) { 
    this.window = window; 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
    g.setColor(Color.blue); 
    g.fillRect(0, 0, 320, 240); 
    } 
    } 

    public static void main(String[] args) { 
    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
     new Test(); 
     } 
    }); 
    } 
} 

當我上的IcedTea JVM在Linux上運行它,我看到this

您的問題是由於按鈕容器迫使窗口變寬,或者可能是由於您使用的Java版本中存在Swing錯誤。

我的建議是不要打擾內置佈局類,而是使用MigLayout。

+0

我正在使用Sun Java 6.我還沒有檢查過按鈕容器,但由於兩種情況都使用完全相同的按鈕容器,因此似乎不太可能是問題所在。這不是我想要解決的問題(我可以減小首選大小以使其工作),但我想知道是什麼原因造成的。 – FinalArt2005 2009-10-20 12:32:17

+0

我想對上面的評論之一發表評論,但可以在那裏評論... 幾乎所有的佈局管理器都忽略了最大和最小尺寸,有些並沒有完全按照您期望的尺寸進行設計。 MigLayout尊重所有這些。這會讓你的東西非常接近你要找的東西: background.setLayout(new MigLayout(「ins 5」)); background.add(paintPanel,「w 320!,h 240!,wrap」); background.add(buttonPanel,「gapabove unrel」); http://www.migcalendar.com/miglayout/ – uckelman 2009-10-20 18:19:59

2

信不信由你,但嘗試反向包()和setResizeable()

... 
    frame.setResizable(false); 
    frame.pack(); // should be called after any changes 
    frame.setVisible(true); 

編輯的順序:選中使用此

frame.pack(); 
    frame.setResizable(false); 
    System.out.println(paintPanel.getSize()); 
    frame.setVisible(true); 
    System.out.println(paintPanel.getSize()); 

frame.setResizable(false); 
    frame.pack(); 
    System.out.println(paintPanel.getSize()); 
    frame.setVisible(true); 
    System.out.println(paintPanel.getSize()); 

但如果大小不重要,您可以填寫實際區域

@Override 
public void paintComponent(Graphics g) { 
    g.setColor(Color.blue); 
    g.fillRect(0, 0, getWidth(), getHeight()); 
} 

[]]

+0

感謝您的提示,但它也沒有擺脫邊界。 – FinalArt2005 2009-10-20 13:44:17

+0

在這裏工作正常,沒有ButtonPanel(沒有代碼),我只是得到了5x5邊框(EmptyBorder)。在Windows XP上使用Java build 1.6.0_16-b01 – 2009-10-20 13:51:26

+0

我剛剛發佈setResizable(false)正在影響這一點。如果setResizable(false)/ pack()的順序相反,我也看到它正常工作 - Windows Vista上的JDK 1.5.0_16。 – Nate 2009-10-20 14:11:31