我试图动画2个框从JPanel的右上角到左下角。对于动画我正在使用Swing Timer和SwingUtilities.invokeLater()
。问题是当我点击开始按钮时。它只会动画并移动蓝框,但不会移动红框。
下面是代码:
//import neccessary stuff
public class Example extends JFrame {
public static void main(String[] args) {
Example e = new Example();
e.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
e.setSize(600, 565);
e.setVisible(true);
}</code>
private JButton startButton = new JButton("Start");
private JPanel theTable = new table();
public Example() {
add(startButton, BorderLayout.SOUTH);
add(theTable, BorderLayout.CENTER);
Handler handler = new Handler();
startButton.addActionListener(handler);
}
public ArrayList<Integer> xPos, yPos;
final int START_POSITION_X = 470;
final int START_POSITION_Y = 10;
final int[] END_POSITION_X = {70, 87};
final int END_POSITION_Y = 160;
private class table extends JPanel {
public table() {
xPos = new ArrayList<Integer>();
yPos = new ArrayList<Integer>();
xPos.add(START_POSITION_X); //default position for box1
yPos.add(START_POSITION_Y);
xPos.add(START_POSITION_X); //default position for box2
yPos.add(START_POSITION_Y);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
this.setBackground(new Color(-16756217));
g.setColor(Color.RED);
g.fillRect(xPos.get(1), yPos.get(1), 89, 129);
g.setColor(Color.BLUE);
g.fillRect(xPos.get(0), yPos.get(0), 89, 129);
if (isAnimating) {
animator.start();
} else {
animator.stop();
isAnimating = false;
}
}
}
private class Handler implements ActionListener {
public void actionPerformed(ActionEvent e) {
Runnable r1 = new Runnable() {
@Override
public void run() {
animateCard(0, END_POSITION_X[0], END_POSITION_Y);
}
};
SwingUtilities.invokeLater(r1);
animateCard(1, END_POSITION_X[1], END_POSITION_Y);
}
}
public void animateCard(int card, int xDest, int yDest) {
cardID = card;
xDestination = xDest;
yDestination = yDest;
totalXDistance = Math.abs(xDestination - START_POSITION_X);
totalYDistance = Math.abs(yDestination - START_POSITION_Y);
animator.start();
}
int cardID;
int xDestination, yDestination, totalXDistance, totalYDistance;
boolean isAnimating = false;
Timer animator = new Timer(15, new ActionListener() {
int startVel = 20;
public void actionPerformed(ActionEvent e) {
double xRelDistance, xAbsDistance, xVel;
int xRealVel;
xAbsDistance = xDestination - xPos.get(cardID);
xRelDistance = xAbsDistance / totalXDistance;
xVel = startVel * xRelDistance;
double yRelDistance, yAbsDistance, yVel;
yAbsDistance = yDestination - yPos.get(cardID);
yRelDistance = yAbsDistance / totalYDistance;
yVel = startVel * yRelDistance;
if (xVel > 0) {
xRealVel = (int) java.lang.Math.ceil(xVel);
} else {
xRealVel = (int) java.lang.Math.floor(xVel);
}
xPos.set(cardID, xPos.get(cardID) + xRealVel);
int yRealVel;
if (xVel > 0) {
yRealVel = (int) java.lang.Math.ceil(yVel);
yPos.set(cardID, yPos.get(cardID) + yRealVel);
} else {
yRealVel = (int) java.lang.Math.floor(yVel);
}
yPos.set(cardID, yPos.get(cardID) + yRealVel);
if ((xPos.get(cardID) == xDestination) && (yPos.get(cardID) == yDestination)) {
isAnimating = false;
} else {
isAnimating = true;
}
repaint();
}
});
}
答案 0 :(得分:0)
因此,在类级别声明的所有变量都是共享的......您对animateCard
的第一次调用将设置它们,然后您对animateCard
的第二次调用将完全覆盖以前的值。您需要将它们从类变量更改为动画的参数。
创建一个实现AnimationTask
的新类ActionListener
并将变量保存在该类中。
如,
class AnimationTask implements ActionListener {
private int cardID;
private int xDest;
private int yDest;
private int totalXDistance;
private int totalYDistance;
public AnimationTask(int cardID, int xDest, int yDest) {
this.cardID = cardID;
this.xDest = xDest;
this.yDest = yDest;
this.totalXDistance = Math.abs(xDestination - START_POSITION_X);
this.totalYDistance = Math.abs(yDestination - START_POSITION_Y);
}
public void actionPerformed(ActionEvent e) {
// do your animation logic...
}
}
并在“animator”中使用该自定义类
如,
Timer animator = new Timer(15, new AnimationTask(cardId, xDest, yDest);
答案 1 :(得分:0)
把
animateCard(1, END_POSITION_X[1], END_POSITION_Y);
在你的run方法中:
public void run() {
animateCard(0, END_POSITION_X[0], END_POSITION_Y);
}