2 回答

TA貢獻1784條經驗 獲得超9個贊
所以你遇到了很多問題。首先,窗口的大小還必須考慮框架裝飾,這意味著內容的可用空間是窗口的大小減去框架裝飾的大小。
直接設置窗口的大小是不明智的。
pack詢問框架的內容以獲得它的首選大小,并使用它來環繞它的窗口。所以,而不是window size - decorations = content size,你有content size + decorations = window size
來自JavaDocs
使此窗口的大小適合其子組件的首選大小和布局。如果任一維度小于先前調用 setMinimumSize 方法指定的最小尺寸,則生成的窗口寬度和高度將自動放大。
所以,相反,覆蓋preferredSize了的Game類并返回你想要的空間大小,可能是類似...
public class Game extends JPanel {
//...
@Override
public Dimension getPreferredSize() {
return new Dimension(800, 600);
}
//...
}
你的下一個問題是,Windowextends from JFrame,但在構造函數中,你正在創建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 上運行。setResizable我在 Windows 上遇到過一個鮮為人知的問題,窗口裝飾在setResizable被調用時會改變大小。
“基本”解決方案是調用setResziableBEFORE 調用pack,以便在 API 決定如何更新窗口大小之前修改框架裝飾。
我原以為這會在以后的 (8+) 版本的 Java 中修復,但由于我不運行 Windows,因此無法進行測試

TA貢獻1860條經驗 獲得超8個贊
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);
}
}
使用 pack 時,框架通常會調整為內容大小
添加回答
舉報