java - JPanel 不填充包含 JFrame

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

}

这是我的第二个类,扩展 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 的首选大小 EnginePanel 限制面板的大小调整 JFrame 呈现为不可调整大小。在调用 setResizable(false) 之后调用 JFrame#pack。在 pack 之后移动 setLocationRelativeTo,使框架居中显示。

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

关于java - JPanel 不填充包含 JFrame,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17241435/

相关文章:

java - 将 Jar-URI 转换为 nio.Path

java - 删除或隐藏 JScrollPane 错误

java - 更改 NetBeans UI 外观/感觉

java - 线程中的异常 "main"java.lang.IllegalArgumentException : setSelectedIndex: 4 out of bounds

java - Java(Spring 应用程序)和 C# 之间的数据交换

java - 在 Amazon DynamoDB 中添加/删除项目到数组

Java Swing : main class wait until JFrame is closed

java - JLabel setLocation 不起作用?

java - 使用 Jackson 将 Java 列表序列化为 XML 和 JSON

java - 一步而不是三步撤消 JEditorPane 的 setText() 方法的效果