[英]JFrame too small and pack() doesn't seem to work
由于某些原因,运行和使用pack();
时JFrame太小pack();
似乎无法解决问题。 有任何想法吗?
public class Window {
public Window(String title, Game game) {
// Creates new JFrame
JFrame frame = new JFrame(title);
// Adds Game to window
frame.add(game);
frame.pack();
// Settings of Window
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
青色的背景应该是底部和右侧的64 x 64边框。 绘制的框是正确的,我通过调整窗口大小来检查。 但是,窗口太小,无法容纳画布。
游戏类别:
public class Game extends Canvas implements Runnable {
private Handler handler;
public Game() {
// Create new window
Window window = new Window("Horses Aren't Real", this);
handler = new Handler();
this.addKeyListener(new KeyInput(handler));
handler.addObject(new Daanish(100, 100, ID.Player, handler));
}
public static void main (String args[]) {
// Creates new game
new Game();
}
public void draw() {
// Creates a new BufferStrategy
BufferStrategy bs = this.getBufferStrategy();
if (bs == null) {
// This allows the game to preload 3 frames in order to prevent choppy framrate
this.createBufferStrategy(3);
return;
}
// Create Graphics
Graphics g = bs.getDrawGraphics();
g.setColor(Color.cyan);
g.fillRect(0, 0, 1024, 640);
g.setColor(Color.black);
g.fillRect(0, 0, 960, 576);
handler.draw(g);
// Remove frame from queue
g.dispose();
bs.show();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(1024, 640);
}
}
因此,您遇到了许多问题。 首先,窗口的大小还必须考虑框架装饰,这意味着内容的可用空间是窗口的大小减去框架装饰的大小。
建议不要直接设置窗口的大小。
pack
询问框架的内容以获取其首选大小,然后使用该大小将窗口包裹在框架周围。 因此,您可以使用content size + decorations = window size
,而不是window size - decorations = content size
content size + decorations = window size
使此窗口的大小适合其子组件的首选大小和布局。 如果任意一个尺寸小于上一次调用setMinimumSize方法指定的最小尺寸,则窗口的宽度和高度将自动放大。
因此,改为重写Game
类的preferredSize
并返回所需的空间量,可能类似于...
public class Game extends JPanel {
//...
@Override
public Dimension getPreferredSize() {
return new Dimension(800, 600);
}
//...
}
下一个问题是, Window
是从JFrame
扩展而来的,但是在构造函数中,您正在创建ANOTHER Frame
...那么哪个实际上在做什么?
消除混乱。 避免从诸如JFrame
类的顶级容器扩展,而不必向其添加任何新功能
public class Window {
public Window(String title, Game game) {
// Creates new JFrame
JFrame frame = new JFrame(title);
// Adds Game to window
frame.add(game);
frame.pack();
// Settings of Window
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
因此,我采用了您的“更新”代码,对其进行了修改,使其可以运行,运行并且没有任何问题...
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
Game game = new Game();
Window window = new Window("Help", game);
game.start();
}
});
}
public class Window {
public Window(String title, Game game) {
// Creates new JFrame
JFrame frame = new JFrame(title);
// Adds Game to window
frame.add(game);
frame.setResizable(false);
frame.pack();
// Settings of Window
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
public class Game extends Canvas { //implements Runnable {
// private Handler handler;
public Game() {
//
// handler = new Handler();
// this.addKeyListener(new KeyInput(handler));
//
// handler.addObject(new Daanish(100, 100, ID.Player, handler));
}
public void start() {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
draw();
try {
Thread.sleep(40);
} catch (InterruptedException ex) {
}
}
}
});
thread.start();
}
public void draw() {
// Creates a new BufferStrategy
BufferStrategy bs = this.getBufferStrategy();
if (bs == null) {
// This allows the game to preload 3 frames in order to prevent choppy framrate
this.createBufferStrategy(3);
return;
}
// Create Graphics
Graphics g = bs.getDrawGraphics();
g.setColor(Color.cyan);
g.fillRect(0, 0, 1024, 640);
g.setColor(Color.black);
g.fillRect(0, 0, 960, 576);
// handler.draw(g);
// Remove frame from queue
g.dispose();
bs.show();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(1024, 640);
}
}
}
但是,我在MacOS上运行。 我在Windows上遇到过setResizable
一个鲜为人知的问题,在调用setResizable
时,窗口装饰会更改大小。
“基本”解决方案是在调用pack
之前调用setResziable
,以便在API决定如何更新窗口大小之前修改框架装饰。
我以为这已在Java的更高版本(8+)中修复,但是由于我没有运行Windows,因此无法测试
请参阅My JFrame总是变得太大了几个像素。 有关更多详细信息。
public class Window extends JFrame {
public Window(final int width, final int height, String title, Game game) {
super(title);
// Set dimensions
Dimension d = new Dimension(width, height);
game.setPreferredSize(d);
// Adds Game to window
add(game);
// Settings of Window
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
pack();
setVisible(true);
}
}
使用包时,框架通常会调整为内容大小
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.