gpt4 book ai didi

java - 使用计时器为 JPanel(滑入)设置动画

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:29:51 25 4
gpt4 key购买 nike

我正在尝试使用我创建的此类从侧面滑入 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 直到循环完成,从而防止更新界面

用例子更新

例如……

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 年不想 sleep ,2 位 parent 这样做了,不要再说了......)

动画是一个复杂的主题,尤其是当您开始研究变速时(示例是静态的)。

与其重新发明轮子,您应该认真考虑看看...

关于java - 使用计时器为 JPanel(滑入)设置动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16316132/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com