Java,当面板改变大小时改变框架的大小,家庭作业
新手,请容忍我。我正在用Java编写一个Sokoban游戏,我启动了这个游戏,但我在使用pack()时遇到了问题。我想我的框架调整自己的大小取决于水平的大小,不同的水平有不同的大小。对于不同的尺寸,面板的绘制是正确的,因此如果我只是最大化框架,那么一切都很好,但是如何调用pack()来自动调整框架的大小呢?我试图将pack()放在我的Main方法中,但我怀疑解决方案不是那么简单(可能我构建程序的方式也没有帮助)。将pack()放在Main方法中会生成附加的图像,这是一个非常小的矩形,基本上只有min、max和close按钮 我想实施的建议解决方案如下: 编写Sokoban构造函数,使其将周围的JFrame作为引用参数,然后对象在字段中记住该参数。然后,在更改Sokoban组件的首选大小后,调用此存储框架的方法包 我已经附上了我的构造函数和Main方法的代码Java,当面板改变大小时改变框架的大小,家庭作业,java,swing,Java,Swing,新手,请容忍我。我正在用Java编写一个Sokoban游戏,我启动了这个游戏,但我在使用pack()时遇到了问题。我想我的框架调整自己的大小取决于水平的大小,不同的水平有不同的大小。对于不同的尺寸,面板的绘制是正确的,因此如果我只是最大化框架,那么一切都很好,但是如何调用pack()来自动调整框架的大小呢?我试图将pack()放在我的Main方法中,但我怀疑解决方案不是那么简单(可能我构建程序的方式也没有帮助)。将pack()放在Main方法中会生成附加的图像,这是一个非常小的矩形,基本上只有m
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);
}
编写Sokoban构造函数,使其将周围的JFrame作为引用参数,然后对象在字段中记住该参数。然后,在更改Sokoban组件的首选大小后,调用此存储框架的方法包
答案已更新为@mKorbel建议的用法(感谢您的提示,代码现在看起来更干净了)
您的fried试图告诉您的是创建这样的东西(我删除了您在本例中不需要的代码)
在构造函数publicsokoban(字符串文件名,JFrame-tframe)
中,您需要传递对包含Sokoban面板的框架的引用。您需要将该引用中的对象存储在类中的某个位置,比如类字段private JFrame代码>
现在,由于该引用,无论何时更改面板的大小,您都可以通过调用frame.pack()
来使用它来更改包含该面板的框架的大小,并使其适应新的大小。这可能不会解决您的问题,但使用frame.setVisible(true)是一种很好的做法代码>将所有内容添加到框架后,请尝试在setDefaultCloseOperation
@Pshemo之后移动它,注意,谢谢!另外,您应该使用jframe.getContentPane().add()
?与只添加相比,add
@Patrick,谢谢,jframe.getContentPane().add()的优点是什么?没有什么好处,add
只是在后台调用getContentPane
,但它让其他人更清楚地看到,您实际上是在向contentpane添加控件,而不是根窗格。您可以在jframe的文档中阅读,谢谢,我无法完全按照您的建议实施解决方案,但我能够使用您的想法来解决我的问题。我无法使用setPreferredSize使其工作,但我使用setSize使其工作。我认为setPreferredSize比setSize更受欢迎?还有,为什么要使用布尔值调整大小?为什么不直接调用frame.pack而不先设置needResize,然后检查是否设置了needResize?@user1894469我不知道为什么,但有时当frame不需要调整大小,我调用pack
时,它会阻止下一次调整大小。这就是为什么我使用flag来检查是否需要调整大小。setPreferredSize
是否优于setSize
?我不知道。我无法使用setSize+pack调整大小,因此我使用setPreferredSize。无论如何,我回答的主要目的是展示在Sokoban构造函数中传递对框架的引用的想法,其余的并没有那个么重要。
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);
}
}