2

新手,请多多包涵。我正在用 Java 编写一个推箱子游戏,我启动了游戏,但是我遇到了 pack() 的问题。我希望我的框架根据关卡的大小自行调整大小,不同的关卡有不同的大小。面板正在为不同的尺寸正确绘制,所以如果我只是最大化框架,那么一切都很好,但是我如何调用 pack() 来自动调整框架的大小?我试图将 pack() 放在我的 Main 方法中,但我怀疑解决方案不是那么简单(可能我构建程序的方式也无济于事)。将 pack() 放在 Main 方法中会生成附加的图像,一个非常小的矩形,基本上只有最小、最大和关闭按钮。框架

我想实施的推荐解决方案如下:

编写 Sokoban 构造函数,使其将周围的 JFrame 作为引用参数,然后对象在字段中记住该参数。然后,在您更改推箱子组件的首选大小后,调用此存储的周围 JFrame 的方法包。

我附上了我的构造函数和 Main 方法的代码。

public class Sokoban extends JPanel {

LevelReader lReader = new LevelReader();      
private static final int SQUARESIZE = 50;  // square size in pixels
int currentLevel = 0;
int height = 0;
int width = 0;
int x = 0;
int y = 0;
Contents [][] mapArray;

public Sokoban(String fileName) {
    lReader.readLevels(fileName);
    initLevel(currentLevel);
    KeyListener listener = new MyKeyListener();
    addKeyListener(listener);
    this.setPreferredSize(new Dimension(500,500));
    setFocusable(true);

}

public static void main(String[] args) {
    JFrame frame = new JFrame("Sokoban");
    Sokoban sokoban = new Sokoban("m1.txt");
    frame.add(sokoban);
    frame.setVisible(true);
    frame.pack();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
4

1 回答 1

2

编写 Sokoban 构造函数,使其将周围的 JFrame 作为引用参数,然后对象在字段中记住该参数。然后在更改推箱子组件的首选大小后,调用此存储的周围 JFrame 的方法包

答案已更新为使用@mKorbel 建议的键绑定(感谢提示,代码现在看起来更干净了)

你的 Fried 想要告诉的是创建这样的东西(我删除了你在这个例子中不需要的代码)

class Sokoban extends JPanel {

    private JFrame frame;

    private class MyAction extends AbstractAction {
        private Dimension dimension;

        public MyAction(Dimension dimension) {
            this.dimension = dimension;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            //we will pack only when dimensions will need to change
            if (!getPreferredSize().equals(dimension)) {
                setPreferredSize(dimension);
                frame.pack();
            }
        }
    }

    public Sokoban(String fileName, JFrame tframe) {
        this.frame = tframe;
        setFocusable(true);
        setPreferredSize(new Dimension(100, 100));
        setBackground(Color.red);
        add(new JLabel("press A, S, D"));

        getInputMap().put(KeyStroke.getKeyStroke('a'), "typed a");
        getInputMap().put(KeyStroke.getKeyStroke('s'), "typed s");
        getInputMap().put(KeyStroke.getKeyStroke('d'), "typed d");

        getActionMap().put("typed a", new MyAction(new Dimension(100, 100)));
        getActionMap().put("typed s", new MyAction(new Dimension(200, 100)));
        getActionMap().put("typed d", new MyAction(new Dimension(100, 200)));
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("Sokoban");
        Sokoban sokoban = new Sokoban("m1.txt", frame);

        frame.setContentPane(sokoban);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
}

在构造函数public Sokoban(String fileName, JFrame tframe)中,您需要传递对包含推箱子面板的框架的引用。您需要将该引用中的对象存储在类中的某个位置,例如在类字段中private JFrame frame;

现在感谢该参考,每当您更改面板的大小时,您都可以使用它通过调用来更改包含该面板的框架的大小,frame.pack()并使其适应新的大小。

于 2013-04-14T15:17:53.213 回答