嗨,所以我正在写一个简单的物理引擎来理解对象冲突和Java图形好一点,到目前为止,我已经成功地编写了代码添加JPanel到JFrame,并允许他们显示出正确的大小,但是当我查看实际的程序时,JPanel似乎是正确的大小,但它不是从窗口的上角开始,而是从帧的左上角开始。我似乎有这个问题很多,我想要的东西在(0,0),并开始在框架的上角而不是面板。这里是我的代码:JPanel不填充包含JFrame
我有一个扩展的JFrame,其中包含主要方法的引擎类 - >
package io.shparki.PhysicsEngine;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import javax.swing.JFrame;
public class Engine extends JFrame{
public Engine(){
super("Physics Engine and Simulator");
setLayout(new BorderLayout());
add(new EnginePanel(), BorderLayout.CENTER);
pack();
setResizable(false);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args){
new Engine();
}
}
,这是我的第二类扩展JPanel并实现Runnable的EnginePanel - >
package io.shparki.PhysicsEngine;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import javax.swing.JPanel;
public class EnginePanel extends JPanel implements Runnable{
private static final int WIDTH = 300;
private static final int HEIGHT = WIDTH/16 * 9;
private static final int SCALE = 4;
public int getWidth() { return WIDTH * SCALE; }
public int getHeight() { return HEIGHT * SCALE; }
@Override
public Dimension getPreferredSize(){ return new Dimension(WIDTH * SCALE, HEIGHT * SCALE); }
private static final int FPS = 85;
private static final int PERIOD = 1000/FPS;
private int currentFPS = 0;
private Thread animator;
private boolean running = false;
private Graphics dbg;
private Image dbImage = null;
public EnginePanel(){
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();
startEngine();
}
public void startEngine(){
running = true;
animator = new Thread(this, "Animator");
animator.start();
}
public void stopEngine(){
running = false;
}
public void paintComponent(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 run(){
running = true;
init();
Long beforeTime, timeDiff, sleepTime;
while(running){
beforeTime = System.currentTimeMillis();
updateEngine();
renderEngine();
paintScreen();
timeDiff = System.currentTimeMillis() - beforeTime;
sleepTime = PERIOD - timeDiff;
if (sleepTime <= 0){
sleepTime = 5L;
}
currentFPS = (int) (1000/(sleepTime + timeDiff));
try{
Thread.sleep(sleepTime);
} catch (InterruptedException ex) { ex.printStackTrace(); }
}
}
private TextField FPSTextField;
public void init(){
FPSTextField = new TextField("Currnet FPS: " + currentFPS, 25, 25);
}
public void updateEngine(){
FPSTextField.setText("Currnet FPS: " + currentFPS);
}
public void renderEngine(){
if (dbImage == null){
dbImage = createImage((int)getWidth(), (int)getHeight());
if (dbImage == null){
System.out.println("Graphical Context Error : DBImage is Null");
return;
} else {
dbg = dbImage.getGraphics();
}
}
Graphics2D g2d = (Graphics2D) dbg;
g2d.setColor(Color.BLACK);
g2d.fillRect(0, 0, getWidth(), getHeight());
FPSTextField.render(g2d, Color.MAGENTA);
}
}
我不太清楚为什么这种情况持续发生,我寻求帮助但找不到答案。在此先感谢所有帮助谁:)
编辑:添加代码为TextField对象:
package io.shparki.PhysicsEngine;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
public class TextField{
private Point location;
public Point getLocation(){ return location; }
public double getX() { return location.getX(); }
public double getY() { return location.getY(); }
private String text;
public void setText(String text) { this.text = text; }
public String getText() { return this.text; }
public TextField(String text, int x, int y){
this.location = new Point(x, y);
this.text = text;
}
public TextField(String text, Point location){
this.location = location;
this.text = text;
}
public void render(Graphics g){
g.drawString(text, (int)location.getX(), (int)location.getY());
}
public void render(Graphics2D g2d){
g2d.drawString(text, (int)location.getX(), (int)location.getY());
}
public void render(Graphics g, Color color){
g.setColor(color);
g.drawString(text, (int)location.getX(), (int)location.getY());
}
public void render(Graphics2D g2d, Color color){
g2d.setColor(color);
g2d.drawString(text, (int)location.getX(), (int)location.getY());
}
public void render(Graphics g, Color color, Font font){
g.setColor(color);
g.setFont(font);
g.drawString(text, (int)location.getX(), (int)location.getY());
}
public void render(Graphics2D g2d, Color color, Font font){
g2d.setColor(color);
g2d.setFont(font);
g2d.drawString(text, (int)location.getX(), (int)location.getY());
}
}
如果我正确理解你的问题,你问为什么jpanel和jframe容器之间有填充?这是一个默认边框,你可以改变它。 – arynaq
我相信如此。我希望我能更好地提出这个问题,但我不太明白自己在做什么。在JFrame中,我希望面板起源于JFrame窗口的左上角,但是它起源于JFrame本身的左上角(如过去的边框)。我相信,由于这个原因,我在面板的右侧和底部得到了白色的衬垫,尽管它们全都是黑色的。 –