JPanel不填充包含JFrame

时间:2013-06-21 17:52:56

标签: java swing jframe jpanel

嗨,所以我正在编写一个简单的物理引擎来更好地理解对象冲突和Java图形,到目前为止,我已成功编写代码将JPanel添加到JFrame并允许它们显示正确的大小,但是当我查看实际程序时,JPanel似乎是正确的大小,但它不是从窗口的上角开始,而是从框架的左上角开始。我似乎有这个问题很多我想要的东西在(0,0),并开始在框架的上角而不是面板。这是我的代码:

我有一个扩展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();
    }

}

这是我的第二个类,EnginePanel扩展了JPanel并实现了Runnable - >

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());
    }
}

2 个答案:

答案 0 :(得分:3)

JPanel EnginePanel的首选大小限制了面板的大小调整JFrame呈现不可调整大小。在致电JFrame#pack后调用setResizable(false)。同时在包装后移动setLocationRelativeTo,使框架显示为居中。

pack();
setLocationRelativeTo(null);
setVisible(true);

答案 1 :(得分:0)

如果在JFrame中使用GridBagLayout,那么如果它是您添加到JFrame的唯一内容,则JPanel将居中。如果你调整窗口大小,它甚至会留在中心。

此外,坐标似乎不适合您的原因是您将其视为(x,y)坐标,而实际上它是一个(行,col)坐标,就像在2D数组中一样。