在JFrame中使用JPanel不会调整大小或正确移动

时间:2012-11-14 20:09:03

标签: java swing jframe jpanel sizing

感谢您抽出宝贵时间阅读本文。我希望它不会令人困惑,如果需要任何其他信息,请告诉我!

问题: 我正在制作类似Snake的游戏,我创建了一个JFrame,然后添加了JPanel。好吧,如果我没有在JFrame中设置它的大小,它的大小将大约为100 x 20.当我设置它的大小时,它将保持在设置的维度。但是,如果我打包()它,当我在JPanel中定义了大小时,它将缩小回100 x 20左右。我也设定了界限,没有运气。我使用FlowLayout()和BorderLayout()也没有成功。现在我的游戏运行正常并且没有任何问题,除了框架。它会切断两侧,除非我做一些我不想做的体操。

目标: 我希望能够将Frame尺寸正确地指定给我指定的宽度和高度,并让面板向下移动一点,为游戏添加文本空间,这样就不会阻挡任何东西。

基本上我感到困惑和慌张,我已经花了几天时间,到目前为止我还没有成功。

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);
 }
}

我的董事会课程:

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()不会影响结果。

4 个答案:

答案 0 :(得分:5)

您需要使用getPreferred/Minimum/MaximumSize和实际尊重它的布局的组合。

在这里,我使用GridBagLayout设置,以便电路板始终保持相同的大小,但是电池将使用最大量的电池。

如果您想将文字保留在棋盘的底部(而不是框架),请删除weighty约束(可能还有weightx

enter image description here enter 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();
        }

    }    
}

答案 1 :(得分:4)

假设Board主要用于绘图,您可以覆盖getPreferredSize()以返回合适的Dimension。当您pack()封闭Window时,它将采用所选的大小。有关详情,请参阅此Q&A,并避免使用此pitfall

答案 2 :(得分:0)

我知道你说使用setPreferredSize()并没有影响结果,但是其他两个人和我似乎认为应该解决这个问题。你能尝试以下方法:

主要改变这个:

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

要:

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

然后添加pack()并查看结果是否已更改。理论上这应该解决问题,除非我们看不到其他事情。

答案 3 :(得分:0)

我使用swing的首选方法是让内部组件设置其首选大小, 并拥有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));
    }

}