![](/img/trans.png)
[英]JFrame getWidth() and getHeight() return 0 even after pack()
[英]JPanel getWidth() returns Zero, after invoking pack()
我相信我的代碼會描述我寫的內容,但是問題是,當我運行它時,我得到了臭名昭著的“ Animator”線程java.lang.IllegalArgumentException中的異常:寬度(0)和高度(0)不能為<= 0“錯誤。 我已經搜索了答案,但是還沒有找到原因。
package com.shparki.TowerDefense;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import javax.swing.JPanel;
public class GamePanel extends JPanel implements Runnable{
//==================== PROGRAM VARIABLES ====================//
private static final int WIDTH = 300;
private static final int HEIGHT = WIDTH / 16 * 9;
private static final int SCALE = 4;
private static final int TARGET_FPS = 45;
private static final int PERIOD = 1000 / TARGET_FPS;
private boolean debug = true;
private volatile boolean running = false;
private volatile boolean gameOver = false;
private volatile boolean paused = false;
private Thread animator;
private TowerDefense frame;
private double currentFPS;
//==================== PROGRAM METHODS ====================//
public GamePanel(TowerDefense td){
frame = td;
setMinimumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
setVisible(true);
}
public void addNotify(){
super.addNotify();
startGame();
}
public void startGame(){
if (!running && animator == null){
animator = new Thread(this, "Animator");
animator.start();
}
}
public void stopGame(){
running = false;
}
public void run(){
running = true;
Long beforeTime, timeDiff, sleepTime;
while(running){
beforeTime = System.currentTimeMillis();
update();
render();
paintScreen();
timeDiff = System.currentTimeMillis() - beforeTime;
sleepTime = PERIOD - timeDiff;
if (sleepTime <= 0){
sleepTime = 5L;
}
currentFPS = (1000 / ( timeDiff + sleepTime ));
try{
Thread.sleep(sleepTime);
} catch (InterruptedException ex) { ex.printStackTrace(); }
}
System.exit(0);
}
//==================== DRAWING METHODS ====================//
private Graphics dbg;
private Image dbImage;
public void paintComponenet(Graphics g){
super.paintComponent(g);
if (dbImage != null){
g.drawImage(dbImage, 0, 0, null);
}
}
public void paintScreen(){
Graphics g;
try{
g = this.getGraphics();
if (g != null & dbImage != null){
g.drawImage(dbImage, 0, 0, null);
}
Toolkit.getDefaultToolkit().sync();
g.dispose();
} catch (Exception ex) { System.out.println("Graphics context error: " + ex); }
}
public void doubleBuffer(){
if (dbImage == null){
dbImage = createImage(getWidth(), getHeight());
if (dbImage == null){
System.out.println("dbImage is null");
return;
} else {
dbg = dbImage.getGraphics();
}
}
}
//==================== UPDATE METHODS ====================//
public void update(){
}
//==================== RENDER METHODS ====================//
public void render(){
doubleBuffer();
Graphics2D g2d = (Graphics2D) dbg;
g2d.setColor(Color.BLACK);
g2d.fillRect(0, 0, getWidth(), getHeight());
}
}
這是我的框架課:
package com.shparki.TowerDefense;
import java.awt.BorderLayout;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.JFrame;
public class TowerDefense extends JFrame implements WindowListener{
public TowerDefense(String name){
super(name);
setResizable(false);
setLayout(new BorderLayout());
add(new GamePanel(this), BorderLayout.CENTER);
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
}
public void windowActivated(WindowEvent arg0) { }
public void windowClosed(WindowEvent arg0) { }
public void windowClosing(WindowEvent arg0) { }
public void windowDeactivated(WindowEvent arg0) { }
public void windowDeiconified(WindowEvent arg0) { }
public void windowIconified(WindowEvent arg0) { }
public void windowOpened(WindowEvent arg0) { }
public static void main(String[] args){
new TowerDefense("Tower Defense Game");
}
}
JFrame
尚未打包,因此在GamePanel
中要求高度和寬度
dbImage = createImage(getWidth(), getHeight());
導致JPanel
尺寸為0x0
。
原因是在為組件設置了父組件之后,Swing幾乎立即調用addNotify ( startGame
所在的位置)。
您可以在調用startGame
后顯式調用startGame
。
add(gamePanel, BorderLayout.CENTER);
pack();
gamePanel.startGame();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.