简体   繁体   English

JPanel不填充包含JFrame

[英]JPanel does not fill containing JFrame

Hi so I'm writing an simple physics engine to understand object collisions and Java graphics a bit better, and so far I have successfully written the code to add the JPanel to the JFrame and allow them to show up somewhat the correct size, but when I view the actually program, the JPanel seems tobe the right size but it does not start in the upper corner of the window, but rather the upper left of the frame. 嗨所以我正在编写一个简单的物理引擎来更好地理解对象冲突和Java图形,到目前为止我已成功编写代码将JPanel添加到JFrame并允许它们显示一些正确的大小,但是我查看实际的程序,JPanel似乎是正确的大小,但它不是从窗口的上角开始,而是从框架的左上角开始。 I seem to have this problem alot where I want something to be at (0, 0) and starts in the upper corner of the frame rather than the panel. 我似乎有这个问题很多我想要的东西在(0,0),并开始在框架的上角而不是面板。 Here is my code: 这是我的代码:

I have an engine class that extends JFrame and contains the main method --> 我有一个扩展JFrame的引擎类,并包含main方法 - >

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

}

and this is my second class, the EnginePanel which extends JPanel and implements Runnable --> 这是我的第二个类,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);
    }
}

I'm not quite sure why this keeps happening and I have searched for help but can not find the answer. 我不太确定为什么这种情况一直在发生,我一直在寻求帮助,但找不到答案。 Thanks in advance for all who help :) 在此先感谢所有帮助的人:)

EDIT: Added code for the TextField object: 编辑:添加了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());
    }
}

The preferred size of the JPanel EnginePanel restricts the panel from being resized the JFrame is rendered non-resizable. JPanel EnginePanel的首选大小限制了面板的大小调整, JFrame呈现为不可调整大小。 Invoke JFrame#pack after calling setResizable(false) . 调用setResizable(false)后调用JFrame#pack Also move setLocationRelativeTo after pack so that the frame appears centered. 同时在包后移动setLocationRelativeTo ,使框架显示为居中。

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

If you use a GridBagLayout in the JFrame, then the JPanel will be centered if it is the only thing you add to the JFrame. 如果在JFrame中使用GridBagLayout,那么如果它是您添加到JFrame的唯一内容,则JPanel将居中。 It will even stay in the center if you resize the window. 如果你调整窗口大小,它甚至会留在中心。

Also, the reason the coordinates seem off to you is that you are viewing it as an (x, y) coordinate while it is actually a (row, col) coordinate like in a 2D Array. 此外,坐标似乎偏离你的原因是你将它看作(x,y)坐标,而它实际上是一个(行,col)坐标,就像在2D数组中一样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM