java - 获取类外 JPanel 的宽度和高度

标签 java swing jpanel 2d awt

因此,我创建了一个简单的模拟,其中使用随机 vector 和窗口边缘的弹跳随机生成方 block 。

我希望它考虑到正在调整大小的窗口。因此,如果我将窗口的尺寸从 600x600 更改为 1200x600,方 block 将根据新边框反弹,而不是 600x600。

我尝试执行 getWidth() getHeight() 但它会返回 0。 所以我把它放在 pain() 方法中(因为它在窗口调整大小时被调用)并将返回值保存为局部变量。但我无法从 Rect 类调用 getjpWidth()。

所以基本上我需要的是将新的窗口尺寸放入 Rect 类中的 move() 方法中。

请随时指出任何其他错误以及可以做得更好的事情。我是 2D 编程新手(学习计算机科学)

申请

import javax.swing.*;

public class Application {
    private Application(){
        //create a JFrame window
        JFrame frame = new JFrame("Moving Squares");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //add a JPanel
        GamePanel gamePanel = new GamePanel();
        frame.add(gamePanel);
        //pack the window around the content
        frame.pack();
        //center
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String args[]){
        new Application();
    }
}

游戏面板

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

public class GamePanel extends JPanel implements Runnable{
    private int jpWidth=0, jpHeight=0;

    //set JPanel size
    private static final Dimension DESIRED_SIZE = new Dimension(600,600);
    @Override
    public Dimension getPreferredSize(){
        return DESIRED_SIZE;
    }

    //constructor
    GamePanel(){
        Thread t = new Thread(this);
        t.start();
    }

    private ArrayList <Rect> rect=new ArrayList<>();
    public void run(){
        for(int i=0; i<15; i++){
            rect.add(new Rect());
        }
        while(true){
            for(Rect rect:rect){
                rect.move();
            }
            //repaint still image for better frames
            //should be 100fps instead it's >144fps
            repaint();
            try{Thread.sleep(10);}
            catch(InterruptedException e){/**/};
            repaint();
            try{Thread.sleep(10);}
            catch(InterruptedException e){/**/};
            repaint();
            try{Thread.sleep(10);}
            catch(InterruptedException e){/**/};
        }
    }

    public void paint(Graphics g){
        Graphics2D g2d = (Graphics2D) g.create();
        jpWidth=getWidth();
        jpHeight=getHeight();
        g2d.setColor(Color.white);
        g2d.fillRect(0,0,jpWidth,jpHeight);
        for(Rect rect:rect) {
            g2d.setColor(Color.black);
            g2d.fillRect(rect.getXcord()-1, rect.getYcord()-1, rect.getWidth()+2, rect.getHeight()+2);
            g2d.setColor(Color.getHSBColor(rect.getR(), rect.getG(), rect.getB()));
            g2d.fillRect(rect.getXcord(), rect.getYcord(), rect.getWidth(), rect.getHeight());
        }
    }

    public int getJpWidth() {
        return jpWidth;
    }

    public int getJpHeight() {
        return jpHeight;
    }
}

矩形

import java.util.Random;

public class Rect {
    //properties
    private int width=30, height=30;
    private int R, G, B;
    //movement
    private int xCord, yCord;
    private int xVector, yVector;
    private int xSlope, ySlope;

    public Rect(){
        Random rand = new Random();
        //random color
        R=rand.nextInt(255);
        G=rand.nextInt(255);
        B=rand.nextInt(255);

        //random spawn position
        xCord=rand.nextInt(600-width);
        yCord=rand.nextInt(600-height);

        //direction
        do{
            xVector=rand.nextInt(3) - 1;
            yVector=rand.nextInt(3) - 1;
        }while(xVector==0 || yVector==0);

        //slope
        do{
            xSlope=rand.nextInt(3);
            ySlope=rand.nextInt(3);
        }while(xSlope==0 || ySlope==0);
        xVector*=xSlope;
        yVector*=ySlope;
    }

    public void move(){
        //if(xCord>=//how to get screen width ? ){}
        if((xCord>=600-width) || (xCord<=0)){
            bounceX();
        }
        if((yCord>=600-height) || (yCord<=0)) {
            bounceY();
        }
        xCord+=xVector;
        yCord+=yVector;
    }

    public void bounceX(){
        xVector*=-1;
    }

    public void bounceY(){
        yVector*=-1;
    }

    public int getR() {
        return R;
    }

    public int getG() {
        return G;
    }

    public int getB() {
        return B;
    }

    public int getXcord() {
        return xCord;
    }

    public int getYcord() {
        return yCord;
    }

    public int getWidth(){
        return width;
    }

    public int getHeight(){
        return height;
    }
}

最佳答案

So basically what I need is to get new window dimension into the move() method in the Rect class.

不知道这是否是最好的设计,但我将“panel”作为参数传递给“move()”方法,以便可以使用它的宽度/高度。

这里是我周围的一些旧代码,展示了这种方法:

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;

public class BallAnimation4
{
    private static void createAndShowUI()
    {
        BallPanel panel = new BallPanel();

        JFrame frame = new JFrame("BallAnimation4");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( panel );
        frame.pack();
        frame.setLocationRelativeTo( null );
        //frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setVisible( true );

        panel.addBalls(5);
        panel.startAnimation();
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}

class BallPanel extends JPanel implements ActionListener
{
    private ArrayList<Ball> balls = new ArrayList<Ball>();

    public BallPanel()
    {
        setLayout( null );
//      setBackground( Color.BLACK );
    }

    public void addBalls(int ballCount)
    {
        Random random = new Random();

        for (int i = 0; i < ballCount; i++)
        {
            Ball ball = new Ball();
            ball.setRandomColor(true);
            ball.setLocation(random.nextInt(getWidth()), random.nextInt(getHeight()));
//          ball.setMoveRate(32, 32, 1, 1, true);
            ball.setMoveRate(16, 16, 1, 1, true);
//          ball.setSize(32, 32);
            ball.setSize(64, 64);
            balls.add( ball );
        }
    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        for (Ball ball: balls)
        {
            ball.draw(g);
        }
    }

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

    public void startAnimation()
    {
        Timer timer = new Timer(1000/60, this);
        timer.start();
    }

    public void actionPerformed(ActionEvent e)
    {
        move();
        repaint();
    }

    private void move()
    {
        for (Ball ball : balls)
        {
            ball.move(this);
        }
    }


    class Ball
    {
        public Color color = Color.BLACK;

        public int x = 0;
        public int y = 0;
        public int width  = 1;
        public int height = 1;

        private int moveX = 1;
        private int moveY = 1;
        private int directionX = 1;
        private int directionY = 1;
        private int xScale = moveX;
        private int yScale = moveY;

        private boolean randomMove = false;
        private boolean randomColor = false;
        private Random myRand = null;

        public Ball()
        {
            myRand = new Random();
            setRandomColor(randomColor);
        }

        public void move(JPanel parent)
        {
            int iRight = parent.getSize().width;
            int iBottom = parent.getSize().height;

            x += 5 + (xScale * directionX);
            y += 5 + (yScale * directionY);

            if (x <= 0)
            {
                x = 0;
                directionX *= (-1);
                xScale = randomMove ? myRand.nextInt(moveX) : moveX;
                if (randomColor) setRandomColor(randomColor);
            }

            if (x >= iRight - width)
            {
                x = iRight - width;
                directionX *= (-1);
                xScale = randomMove ? myRand.nextInt(moveX) : moveX;
                if (randomColor) setRandomColor(randomColor);
            }

            if (y <= 0)
            {
                y = 0;
                directionY *= (-1);
                yScale = randomMove ? myRand.nextInt(moveY) : moveY;
                if (randomColor) setRandomColor(randomColor);
            }

            if (y >= iBottom - height)
            {
                y = iBottom - height;
                directionY *= (-1);
                yScale = randomMove ? myRand.nextInt(moveY) : moveY;
                if (randomColor) setRandomColor(randomColor);
            }
        }

        public void draw(Graphics g)
        {
            g.setColor(color);
            g.fillOval(x, y, width, height);
        }

        public void setColor(Color c)
        {
            color = c;
        }

        public void setLocation(int x, int y)
        {
            this.x = x;
            this.y = y;
        }

        public void setMoveRate(int xMove, int yMove, int xDir, int yDir, boolean randMove)
        {
            this.moveX = xMove;
            this.moveY = yMove;
            directionX  = xDir;
            directionY  = yDir;
            randomMove  = randMove;
        }

        public void setRandomColor(boolean randomColor)
        {
            this.randomColor = randomColor;

            switch (myRand.nextInt(3))
            {
                case 0:  color = Color.BLUE;
                         break;
                case 1:  color = Color.GREEN;
                         break;
                case 2:  color = Color.RED;
                         break;
                default: color = Color.BLACK;
                         break;
            }
        }

        public void setSize(int width, int height)
        {
            this.width  = width;
            this.height = height;
        }
    }
}

另请注意,对于动画,您应该使用 Swing Timer 来安排动画。 Swing 组件的更新应该在事件调度线程 (EDT) 上完成。虽然这个简单的应用程序不太可能出现问题,但确保遵循这一基本规则是一个好习惯,否则您可能会遇到随机问题,并且调试随机问题绝非易事。

关于java - 获取类外 JPanel 的宽度和高度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54028090/

相关文章:

java - MimeTypeMap 无法返回包含空格的文件名的扩展名

java - 为什么我的 JPanel 上的图像没有更新?

java - 如何获取 JPanel 中文本区域的位置

java - 使用 Java 中的 GridBagLayout 无法正确调整面板大小

java - 确定给定数字 N 是否可以成为具有所有 3 个整数边的直角三角形的斜边的算法

java - 如何从java中的列表返回变量并进入mysql数据库?

java - 当我从图库中选择图像时,onActivityResult 中的 Intent 数据为空

java - 使用 KeyEventDispatcher 设置 jframe 大小

java - 是否可以检测到焦点丢失在 jSpinner 的按钮上

java - 如何删除 jTextArea 的第一行