我正在尝试使用我制作的此类从侧面制作JPanel幻灯片:
public class AnimationClass { private int i; private int y; private JPanel panel; private int xTo; private Timer timer; private int xFrom; synchronized void slidePanelInFromRight(JPanel panelInput, int xFromInput, int xToInput, int yInput, int width, int height) { this.panel = panelInput; this.xFrom = xFromInput; this.xTo = xToInput; this.y = yInput; panel.setSize(width, height); timer = new Timer(0, new ActionListener() { public void actionPerformed(ActionEvent ae) { for (int i = xFrom; i > xTo; i--) { panel.setLocation(i, y); panel.repaint(); i--; timer.stop(); timer.setDelay(100); if (i >= xTo) { timer.stop(); } } timer.stop(); } }); timer.start(); } }
好吧,我不知道问题是什么。我已经尝试了很多不同的方法,但是我似乎无法使其正常工作。
计时器应该在每个刻度上更改其位置,直到它就位为止,相反,您正在运行一个for-next循环,该循环阻止EDT直到循环结束,从而阻止更新UI
更新示例
例如…
import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.Action; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.Timer; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class TestAnimatedPane { public static void main(String[] args) { new TestAnimatedPane(); } public TestAnimatedPane() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } JFrame frame = new JFrame("Test"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class TestPane extends JPanel { private JPanel panel; public TestPane() { setLayout(null); panel = new JPanel(); panel.setBackground(Color.RED); add(panel); Dimension size = getPreferredSize(); Rectangle from = new Rectangle(size.width, (size.height - 50) / 2, 50, 50); Rectangle to = new Rectangle((size.width - 50) / 2, (size.height - 50) / 2, 50, 50); Animate animate = new Animate(panel, from, to); animate.start(); } @Override public Dimension getPreferredSize() { return new Dimension(200, 200); } } public static class Animate { public static final int RUN_TIME = 2000; private JPanel panel; private Rectangle from; private Rectangle to; private long startTime; public Animate(JPanel panel, Rectangle from, Rectangle to) { this.panel = panel; this.from = from; this.to = to; } public void start() { Timer timer = new Timer(40, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { long duration = System.currentTimeMillis() - startTime; double progress = (double)duration / (double)RUN_TIME; if (progress > 1f) { progress = 1f; ((Timer)e.getSource()).stop(); } Rectangle target = calculateProgress(from, to, progress); panel.setBounds(target); } }); timer.setRepeats(true); timer.setCoalesce(true); timer.setInitialDelay(0); startTime = System.currentTimeMillis(); timer.start(); } } public static Rectangle calculateProgress(Rectangle startBounds, Rectangle targetBounds, double progress) { Rectangle bounds = new Rectangle(); if (startBounds != null && targetBounds != null) { bounds.setLocation(calculateProgress(startBounds.getLocation(), targetBounds.getLocation(), progress)); bounds.setSize(calculateProgress(startBounds.getSize(), targetBounds.getSize(), progress)); } return bounds; } public static Point calculateProgress(Point startPoint, Point targetPoint, double progress) { Point point = new Point(); if (startPoint != null && targetPoint != null) { point.x = calculateProgress(startPoint.x, targetPoint.x, progress); point.y = calculateProgress(startPoint.y, targetPoint.y, progress); } return point; } public static int calculateProgress(int startValue, int endValue, double fraction) { int value = 0; int distance = endValue - startValue; value = (int)Math.round((double)distance * fraction); value += startValue; return value; } public static Dimension calculateProgress(Dimension startSize, Dimension targetSize, double progress) { Dimension size = new Dimension(); if (startSize != null && targetSize != null) { size.width = calculateProgress(startSize.width, targetSize.width, progress); size.height = calculateProgress(startSize.height, targetSize.height, progress); } return size; } }
更新资料
我本该在昨晚添加的(1岁不想睡觉的人,2个父母做了,不想再说了……)
动画是一个复杂的主题,尤其是当您开始以可变速度观看时(示例是静态的)。
与其重新发明轮子,不如认真考虑一下…