簡體   English   中英

JFrame getHeight()和getWidth()返回0

[英]JFrame getHeight() and getWidth() return 0

我正在做一個簡單的乒乓球比賽; 並且部分碰撞力學需要獲得畫布的寬度和高度以重定向球。 但是, getWidth()getHeight()由於某種原因返回0。 這是主要的代碼塊。

package pong;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Main extends JPanel {

    static int gameSpeed = 10;
    Ball ball = new Ball(this);

    private void move() {
        ball.move();
    }

    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g;
        ball.paint(g2d);
    }

    public static void main(String args[]) throws InterruptedException {
        JFrame frame = new JFrame("Pong");
        Main game = new Main();
        frame.add(game);
        frame.setSize(400, 400);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        while (true) {
            game.move();
            game.repaint();
            Thread.sleep(gameSpeed);
        }
    }
}

這是實際的Ball類,它處理運動條件。

package pong;

import javax.swing.*;
import java.awt.*;

public class Ball extends JPanel {

    int x = 1;
    int y = 1;
    int dx = 1;
    int dy = 1;
    private Main game;

    public Ball(Main game) {
        this.game = game;
    }

    void move() {
        System.out.println(getWidth() + getHeight());

        if (x + dx < 0) {
            dx = 1;
        }
        if (y + dy < 0) {
            dy = 1;
        }
        if (x + dx > (getWidth() - 30)) {
            dx = -1;
        }
        if (y + dy > (getHeight() - 30)) {
            dy = -1;
        }
        x = x + dx;
        y = y + dy;
    }

    public void paint(Graphics2D g) {
        g.fillOval(x, y, 30, 30);
    }
} 

編輯:問題解決了,我只是沒有告訴getWidth()和getHeight()引用什么。 顯然,如果我不告訴他們要得到什么,他們將返回null。 DERP。 簡單的解決方法是將它們更改為game.getWidth()和game.getHeight()。 謝謝你的幫助! 您的所有輸入也有助於其他領域。 :)

  1. 默認情況下, Graphics / Java2D永遠不會返回合理的Dimension ,結果為零Dimension ,您必須為JPanel覆蓋getPreferredSize ,然后getWidth/Height將返回JPanels大小的正確坐標。

  2. 然后使用JFrame.pack()而不是任何大小調整。

  3. paintComponent 1st中覆蓋Swing JComponents paintComponent ,而不是paint() 代碼行應該是super.paintComponent ,否則繪制累積。

  4. 永遠不要在Swing使用Thread.sleep(int) ,也不要在Java7和Swing中使用自定義繪制或動畫,而是使用Swing Timer而不是Thread.sleep(int)停止的無限循環。

這是一個復雜的問題,由於某些設計決策而變得更糟。

通常,Swing希望組件在布局管理器的約束內使用。 布局管理器需要一定量的信息才能決定如何最好地布局這些組件。 這包括getPreferred/Minimum/Maximum大小。

您遇到的問題是您實際上並不想使用布局管理器,因為您想手動定位Ball 當您拋棄布局管理器時,您將負責大量工作,確保組件在父容器中的大小和位置正確。

一個更簡單的解決方案是生成一個“游戲”表面,您可以在其上繪制游戲元素或實體。

問題是,您似乎不知道要使用哪種方法。 你的BallJPanel擴展,但你的Main面板正在自己繪畫......這不是組件應該如何渲染。

而不是使用組件作為游戲實體的基礎,這會引入許多問題和管理開銷,您可以簡單地使用Main作為主要游戲界面並直接渲染所有實體。 這為您提供了更好的控制並簡化了流程 - 恕我直言

例如...

import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Main extends JPanel {

    public static final int GAME_SPEED = 40;
    Ball ball = new Ball();

    protected void move() {
        ball.move(this);
    }

    public Main() {
        setLayout(null);
        Timer timer = new Timer(GAME_SPEED, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                move();
                repaint();
            }
        });
        timer.start();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g); 
        ball.paint((Graphics2D)g);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(400, 400);
    }

    public static void main(String args[]) throws InterruptedException {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Pong");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                Main game = new Main();
                frame.add(game);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            }
        });
    }

    public interface Entity {

        public void paint(Graphics2D g2d);
        public Rectangle getBounds();

    }

    public interface MovableEntity extends Entity {

        public void move(Container parent);

    }

    public class Ball implements MovableEntity {

        private int dx = 1;
        private int dy = 1;

        private int x;
        private int y;

        @Override
        public void move(Container parent) {

            int width = parent.getWidth();
            int height = parent.getHeight();

            int x = getX();
            int y = getY();

            x += dx;
            y += dy;

            if (x + dx < 0) {
                dx = 1;
            }
            if (y + dy < 0) {
                dy = 1;
            }
            if (x + dx > (width - getBounds().width)) {
                dx = -1;
            }
            if (y + dy > (height - getBounds().height)) {
                dy = -1;
            }

            setLocation(x, y);

        }

        @Override
        public void paint(Graphics2D g2d) {
            int width = getBounds().width;
            int height = getBounds().height;
            int dim = Math.min(width, height);

            int xPos = x + ((width - dim) / 2);
            int yPos = y + ((height - dim) / 2);

            g2d.fillOval(xPos, yPos, dim, dim);
        }

        @Override
        public Rectangle getBounds() {
            return new Rectangle(x, y, 30, 30);
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM