我试图在一帧上显示两个圆圈一起移动 通过两个不同的类。但是,只有一个显示移动,即使值" x"在class1中不断变化,paintComponent()只取值" x1"并显示从class child2移动的圆圈。
如果为两个类分配了两个单独的帧,它们的工作完全正常。 这是我的代码
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Test13
{
public static void main(String[] args)
{
child1 c1 = new child1();
child2 c2 = new child2();
JFrame f1 = new JFrame("Frame Test1");
f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//passing a single JFrame to both methods as parameters
c1.cfunc1(f1);
c2.cfunc2(f1); // but this line always hides the upper one
f1.setSize(1000,700);
f1.setVisible(true);
}
}
class child1 extends JPanel implements ActionListener
{
int x,y;
int delay1;
Timer timer1; //timer for 1st class constructor
child1()
{
x=1;
y=100;
timer1 = new Timer(50,this);
}
@Override
public void actionPerformed(ActionEvent e)
{
if(x <= 500)
{
x += 1;
y = 100;
repaint();
}
}
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.fillOval(x, y, 10, 10);
}
void cfunc1(JFrame f1)//passing JFrame as parameter
{
child1 c1 = new child1();
f1.add(c1);
c1.timer1.start(); //timer started at the end of class1
}
}
class child2 extends JPanel implements ActionListener
{
int x1,y1;
int delay2;
Timer timer2;
child2()
{
x1 = 500;
y1 = 100;
timer2 = new Timer(50,this);//timer for 2nd class constructor
}
@Override
public void actionPerformed(ActionEvent e)
{
if(x1 <= 500)
{
x1 -= 1;
y1 = 100;
repaint();
}
}
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.fillOval(x1, y1, 10, 10);
}
void cfunc2(JFrame f1)//passing JFrame as parameter
{
child2 c2 = new child2();
f1.add(c2);
c2.timer2.start();//timer started for 2nd class
}
}
答案 0 :(得分:4)
当两个组件添加到BorderLayout
的单个约束(JFrame
的默认布局)时,只显示一个。
执行此操作的典型方法不是在JComponent
(如JPanel
)中设计自定义绘画,而是将它们设为可以paint(Graphics)
或{{1当被要求这样做时。
然后扩展一个draw(Graphics)
,它迭代一个可绘制组件的列表并绘制每个组件。
答案 1 :(得分:2)
不要为每个对象创建单独的类(child1,child2)。如果你想要50件物品怎么办?而是创建一个接受允许您自定义对象的参数的类。
此示例显示了您的方式:
draw(...)
方法创建一个自定义绘画的面板。以下是代码:
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.setMoveRate(16, 16, 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;
}
}
}
通常你不会使这些类成为静态的。