2012-11-14 130 views
1

感謝您抽出時間閱讀本。我希望它不會造成混淆,如果需要其他信息,請告訴我!內用JFrame的一個JPanel沒有大小和位置正確

Issue: 我在製作一個類似Snake的遊戲,並創建了一個JFrame,然後添加了JPanel。那麼,如果我沒有在JFrame中設置它的大小,它的大小就會達到100 x 20左右。當我設置它的大小時,它將保持在設置的尺寸上。但是,如果我打包()它,當我在JPanel中定義大小時,它會縮回到100 x 20左右。我也設置了界限,沒有運氣。我使用FlowLayout()和BorderLayout()也沒有成功。現在我的遊戲運行正常,除了幀以外沒有任何問題。它會切斷雙方,除非我做一些我不想做的體操。

目標: 我希望能夠正確地指定幀的大小以適應指定的寬度和高度,並讓面板向下移動一點,爲遊戲文本添加空間,以免阻塞任何內容。

基本上我很困惑與慌張,我已經花了幾天就這一點,我還沒有成功的任何東西爲止。

JFrame類:

public class main extends JFrame { 

/** 
    * @param args the command line arguments 
    */ 

public main(){ 
    Board game = new Board(); 

    setLayout(new BorderLayout(0, 50)); 
    setSize(game.getGameWidth(), game.getGameHeight()); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    setLocationRelativeTo(null); 
    setTitle("BlockRunner"); 
    getContentPane().add(game); 

    setResizable(false); 
    setVisible(true); 
} 
} 

我Board類:

public class Board extends JPanel implements ActionListener, KeyListener{ 
private int width = 600; 
private int height = 400; 
Board(){ 
    addKeyListener(this); 
    setFocusable(true); 
    setBackground(Color.LIGHT_GRAY); 
    setSize(width, height); 
    InitGame(); 
} 
} 

我願意嘗試任何事情有人願意拿出有我。 謝謝你的時間!

編輯1 :(由於用戶的回答。) 使用setPerferredSize(),setMinmumSize()和setMaximumSize()不會影響結果。

+0

有你嘗試setPrefferedSize()? –

+0

@FredrikLS閱讀編輯:P – WilliamShatner

+0

@WilliamShatner確定 –

回答

5

您需要使用的getPreferred/Minimum/MaximumSize組合,這將真正尊重它的佈局。

在這裏,我用了一個GridBagLayout設置,使董事會將始終保持相同的大小,但是電池將使用相同的最高金額。

如果你想保持在板(而不是幀)的底部的文本,刪除weighty約束(以及可能的weightx)以及

enter image description hereenter image description here

public class TestBoardGame { 

    public static void main(String[] args) { 
     new TestBoardGame(); 
    } 

    public TestBoardGame() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException ex) { 
       } catch (InstantiationException ex) { 
       } catch (IllegalAccessException ex) { 
       } catch (UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Test"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new GridBagLayout()); 

       GridBagConstraints gbc = new GridBagConstraints(); 
       gbc.gridx = 0; 
       gbc.gridy = 0; 
       gbc.weightx = 1; 
       gbc.weighty = 1; 
       frame.add(new BoardGamePane(), gbc); 

       gbc.gridx = 0; 
       gbc.gridy = 1; 
       gbc.weightx = 1; 
       gbc.fill= GridBagConstraints.HORIZONTAL; 
       JLabel text = new JLabel("Area for text"); 
       text.setHorizontalAlignment(JLabel.CENTER); 
       frame.add(text, gbc); 

       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 

     }); 
    } 

    public class BoardGamePane extends JPanel { 

     public BoardGamePane() { 

      setBorder(new LineBorder(Color.RED)); 
      setBackground(Color.ORANGE); 

     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(400, 300); 
     } 

     @Override 
     public Dimension getMinimumSize() { 
      return getPreferredSize(); 
     } 

     @Override 
     public Dimension getMaximumSize() { 
      return getPreferredSize(); 
     } 

    }  
} 
+0

您的代碼是更好然後你的文字...覆蓋'getPreferredSize'如果你做的風俗畫好遠,然後調用'setPreferredSize' – Robin

+0

@robin同意,感謝擡頭 – MadProgrammer

+0

@MadProgrammer感謝張貼這個了!非常有助於理解什麼是垃圾內容提及 – WilliamShatner

0

我知道你說的是使用setPreferredSize()不影響結果,但其他兩個和我認爲它是什麼應該修復它。你可以嘗試以下方法:

在主要變化如下:

setSize(game.getGameWidth(), game.getGameHeight()); 

要:

setPreferredSize(new Dimension(game.getGameWidth(), game.getGameHeight())); 

然後加入pack(),看看結果發生了變化。理論上這應該解決這個問題,除非別的事情正在發生,我們看不到。

+0

[我應避免使用一套(首選|最大|最小)中的Java Swing大小的方法(http://stackoverflow.com/q/7229226/230513)? – trashgod

+0

@trashgod感謝您的鏈接:)它確實有助於MadProgrammer的示例顯示了您剛纔提到的內容。我被告知了幾次,以避免'setPreferredSize',並想知道爲什麼。 – WilliamShatner

+0

是的,[示例](http://stackoverflow.com/a/13387411/230513)說明了通過重寫'getXxxSize()'提供的靈活性和可靠性。關於'pack()'的觀點很好用;如果你更新這個答案,請ping我。 – trashgod

4

假設Board主要用於繪圖,您可以覆蓋getPreferredSize()以返回合適的Dimension。當你pack()封閉Window,它將採用所選大小。看到這個Q&A更多,而避免這種pitfall

+0

另請參閱此中相關的[center] [答案](http://stackoverflow.com/a/12024012/230513)。 – trashgod

+0

董事會曾用於基本控制遊戲。儘管非常感謝你的幫助!它幫助我更好地編寫Java GUI。 – Twister1002

0

我優選使用擺動的方式是使內部組件設置其優選尺寸, 並具有JFrame的包。

所以總共需要:在JFrame中

  • 刪除的setSize(或更改了setPreferredSize)中的JPanel
  • 變化的setSize到了setPreferredSize。
  • 一切完成後,在JFrame中調用包。

看看下面的代碼,你想要做什麼。

public class Main extends JFrame { 

    public Main() { 
     Board game = new Board(); 

     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     { 
      Container contentPane = getContentPane(); 
      contentPane.setLayout(new BorderLayout(0, 50)); 
      JLabel label = new JLabel("hello world!"); 
      contentPane.add(label, BorderLayout.NORTH); 
      contentPane.add(game, BorderLayout.CENTER); 
     } 
     pack(); 

     setResizable(false); 
     setVisible(true); 
    } 

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

public class Board extends JPanel { 
    private int width = 600; 
    private int height = 400; 

    Board() { 
     setFocusable(true); 
     setBackground(Color.LIGHT_GRAY); 
     setPreferredSize(new Dimension(width, height)); 
    } 

} 
+0

[我應該避免使用Java Swing中的set(Preferred | Maximum | Minimum)Size方法](http://stackoverflow.com/q/7229226/230513)? – trashgod

+0

謝謝你的鏈接,但這些都是他個人的感覺,不是。首選大小隻是佈局管理器的「指導線」。有一次我實現了自己的佈局管理器,我可以選擇忽略首選大小或使用它。他們真的沒有錯。 – Billiska

+0

與過去經驗實現組件庫的經驗以及看到'setXxxSize()'被濫用的kleopatra的個人感受不同。可悲的是,Twister1002要求我們猜測爲什麼'Board'沒有合理迴應'pack()'。 – trashgod