Java,当Panel改变大小时,改变Frame的大小,作业

时间:2013-04-14 14:16:50

标签: java swing

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

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

编写你的Sokoban构造函数,以便它将周围的JFrame作为参考参数,然后你的对象会在一个字段中记住。然后在更改Sokoban组件的首选大小后,调用此存储的周围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);
}

1 个答案:

答案 0 :(得分:2)

  

编写你的Sokoban构造函数,以便它将周围的JFrame作为参考参数,然后你的对象会在一个字段中记住。然后在更改Sokoban组件的首选大小后,调用此存储的周围JFrame的方法包

根据@mKorbel的建议更新答案以使用key binding(感谢提示,代码现在看起来更干净)

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

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)中,您需要传递对包含Sokoban面板的框架的引用。您需要在类的某个位置存储该引用的对象,例如在类字段private JFrame frame;中。

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