获取类外JPanel的宽度和高度
Posted
技术标签:
【中文标题】获取类外JPanel的宽度和高度【英文标题】:get width and height of JPanel outside of the class 【发布时间】:2019-05-30 09:14:27 【问题描述】:所以我创建了一个简单的简单模拟,其中随机产生的正方形带有随机向量和窗口边缘的反弹。
我希望它考虑到正在调整大小的窗口。因此,如果我将窗口的尺寸从 600x600 更改为 1200x600,方块将反弹新边框而不是 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();
tryThread.sleep(10);
catch(InterruptedException e)/**/;
repaint();
tryThread.sleep(10);
catch(InterruptedException e)/**/;
repaint();
tryThread.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;
【问题讨论】:
最终结果link 【参考方案1】:所以基本上我需要的是在 Rect 类的 move() 方法中获取新的窗口尺寸。
不知道这是否是最好的设计,但我将“面板”作为参数传递给“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) 上完成。虽然这个简单的应用程序不太可能导致问题,但确保遵循此基本规则是一个好习惯,否则您可能会遇到随机问题,而且调试随机问题绝非易事。
【讨论】:
效果很好。谢谢你。我永远不会想到这个如此明显的解决方案:D以上是关于获取类外JPanel的宽度和高度的主要内容,如果未能解决你的问题,请参考以下文章