我正在尝试构建一个方法“move()”,当使用frame.setLocation(int x,int y)方法移动JFrame时,我可以使用该方法设置从开始到结束位置的方式。我尝试了以下内容,它将框架放在正确的位置,但问题是动画首先在x轴上向下,然后仅沿着y轴向下,但我的目标是让它看起来像是一个对角线的运动目的地点。我知道它是因为第一个forLoops因为它们没有将setLocation方法的过程分解为单个部分的正确条件,但我完全不知道如何解决这个问题。
$except
提前谢谢!
答案 0 :(得分:2)
Swing是单线程,您需要将for-loop
从主线程移开。 Swing也不是线程安全的,因此对UI状态的任何修改都应该在main(Event Dispatching)线程的上下文中完成 - catch 22 - 最简单的解决方案是使用Swing Timer
有关详细信息,请参阅How to use Swing Timers
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JLabel("Hello"));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
move(frame, 100, 100);
}
});
}
});
}
public static void move(JFrame frame, int deltaX, int deltaY) {
int xMoveBy = deltaX > 0 ? 4 : -4;
int yMoveBy = deltaY > 0 ? 4 : -4;
int targetX = frame.getX() + deltaX;
int targetY = frame.getY() + deltaY;
Timer timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int frameX = frame.getX();
int frameY = frame.getY();
if (deltaX > 0) {
frameX = Math.min(targetX, frameX + xMoveBy);
} else {
frameX = Math.max(targetX, frameX - xMoveBy);
}
if (deltaY > 0) {
frameY = Math.min(targetY, frameY + yMoveBy);
} else {
frameY = Math.max(targetY, frameY - yMoveBy);
}
frame.setLocation(frameX, frameY);
if (frameX == targetX && frameY == targetY) {
((Timer)e.getSource()).stop();
}
}
});
timer.start();
}
}
答案 1 :(得分:-1)
你的第二个循环一直运行直到完成,你需要同时移动框架,只在需要时增加X
或Y
!
public int currentX() {
return (int) frame.getLocation().getX();
}
public int currentY() {
return (int) frame.getLocation().getY();
}
public void move(int x, int y) {
for (int newX = currentX(), newY = currentY(); newX < x || newY < y; ) {
frame.setLocation(newX, newY);
if (newX < x) newX++;
if (newY < y) newY++;
}
}