动画化按钮移动实际上并不是最困难的问题,最困难的问题是试图将数据移动到可以管理的位置以及如何将源组件与目标连接起来.
首先,您需要一种可以跨容器边界移动组件的方法.虽然可能有几种方法可以做到这一点,但最简单的方法可能是使用框架的玻璃窗格
public class AnimationPane extends JPanel {
public AnimationPane() {
setOpaque(false);
setLayout(null);
}
}
这没什么特别的,它只是一个JPanel,它是透明的,没有布局管理器,通常不建议这样做,但是在这种情况下,我们将控制一切.
现在,我们需要某种方式来动画化运动.
public enum Animator {
INSTANCE;
private List animatables;
private Timer timer;
private Animator() {
animatables = new ArrayList<>(25);
timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
IAnimatable[] anins = animatables.toArray(new IAnimatable[animatables.size()]);
for (IAnimatable animatable : anins) {
animatable.update();
}
}
});
timer.start();
}
public void addAnimatable(IAnimatable animatable) {
animatables.add(animatable);
}
public void removeAnimatable(IAnimatable animatable) {
animatables.remove(animatable);
}
}
public interface IAnimatable {
public void update();
}
public interface IMoveAnimatable extends IAnimatable{
public JComponent getSourceComponent();
public IImportable getImportable();
}
因此,Animator是核心的“引擎”,它基本上是一个Swing Timer,它仅对其可能管理的任何IAnimatable调用更新.这种方法的目的是可以运行许多动画,但是由于只有一个更新/计时器点,因此不会(极大地)降低系统性能.
IAnimatable接口仅定义提供动画功能的基本协定.
我们需要定义某种合同,定义对象可以参与动画过程并接收信息,也就是“目标”
public interface IImportable {
public JComponent getView();
public void importValue(String value);
}
public abstract class AbstractImportable extends JPanel implements IImportable {
@Override