在类之外获取JPanel的宽度和高度 [英] get width and height of JPanel outside of the class

查看:319
本文介绍了在类之外获取JPanel的宽度和高度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我创建了一个简单的简单模拟,其中随机生成带有随机向量的正方形并弹开窗口边缘.

So I created a simple simple simulation where squares are spawned randomly with random vectors and bounce of the edges of the window.

我希望它考虑到正在调整窗口大小.因此,如果我将窗口的尺寸从600x600更改为1200x600,则正方形将跳出新边框,而不是600x600.

I wanted it to take into account the window being resized. So that if I change the dimensions of the window from 600x600 to 1200x600 the squares will bounce of the new border rather than 600x600.

我尝试做getWidth()getHeight(),但它将返回0. 因此,我将其放入pain()(因为它在窗口调整大小时被调用)方法中,并将返回值保存为局部变量.但是我不能从Rect类中调用getjpWidth().

I tried doing getWidth() getHeight() but it would return 0. So I put it in the pain() (since it gets called on window resize) method and saved the return values as local variables. But I cannot call getjpWidth() from the Rect class.

所以基本上,我需要的是在Rect类的move()方法中获得新的窗口尺寸.

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

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

Please feel free to point out any other mistakes and things that can be done better. I'm new to 2D programming (studying Computer Science)

应用

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

GamePanel

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

Rect

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

推荐答案

所以基本上,我需要的是在Rect类的move()方法中获得新的窗口尺寸.

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

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

Don't know if it is the best design but I pass the "panel" as a parameter to the "move()" method so its width/height can be used.

这里有一些我惯用的旧代码,显示了这种方法:

Here is some old code I have lying around that shows this approach:

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.setSize(800, 600);
        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.setSize(32, 32);
            balls.add( ball );
        }
    }

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

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

    public void startAnimation()
    {
        Timer timer = new Timer(75, 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)上完成.虽然不太可能导致这个简单的应用程序出现问题,但是要确保遵循此基本规则是一个好习惯,否则您可能会遇到随机问题,并且调试随机问题绝非易事.

Also, note that for animation you should be using a Swing Timer to schedule the animation. Updates to Swing components should be done on the Event Dispatch Thread (EDT). While not likely to cause a problem with this simple application it is a good habit to make sure this basic rule is followed otherwise you can have random problems and it is never easy to debug a random problem.

这篇关于在类之外获取JPanel的宽度和高度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆