1

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

问题:我正在制作一个类似蛇的游戏,我创建了一个 JFrame,然后添加了 JPanel。好吧,如果我不在 JFrame 中设置它的大小,它将大小约为 100 x 20。当我设置它的大小时,它保持在设置的尺寸。但是,如果我 pack() 它,当我在 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);
 }
}

我的董事会课程:

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

4 回答 4

5

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

在这里,我使用了一个GridBagLayout设置,以便电路板始终保持相同的大小,但单元格将使用最大数量的相同。

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

在此处输入图像描述在此处输入图像描述

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

    }    
}
于 2012-11-14T21:12:46.560 回答
4

假设它Board主要用于绘图,您可以覆盖getPreferredSize()以返回合适的Dimension. 当你pack()封闭Window时,它将采用选择的大小。有关更多信息,请参阅此问答,并避免此陷阱

于 2012-11-14T20:46:36.830 回答
0

我知道你说使用setPreferredSize()不会影响结果,但我和另外两个人似乎认为应该解决它。您可以尝试以下方法:

在主要改变这个:

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

到:

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

然后添加pack(),看看结果有没有变化。从理论上讲,这应该可以解决问题,除非发生了我们看不到的其他事情。

于 2012-11-14T20:43:59.193 回答
0

我使用 swing 的首选方式是让内部组件设置它们的首选大小,并使用 JFrame 包。

所以总的来说,你需要:

  • 删除 JFrame 中的 setSize(或更改为 setPreferredSize)
  • 将 JPanel 中的 setSize 更改为 setPreferredSize。
  • 一切完成后在 JFrame 中调用 pack。

看看下面的代码是否符合您的要求。

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

}
于 2012-11-14T20:55:50.813 回答