我想使用这个类我取得了令从侧面一个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();
}
}
好了,我不知道是什么问题。 我已经尝试了很多不同的东西,但我似乎不喜欢我可以得到它的工作。
计时器应在每个刻度改变位置,直到它在的地方,而是在每个tick,你通过运行一个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对父母做了,不多说了...)
动画是复杂的话题,尤其是当你开始看变速(例子中是静态的)。
相反,重新发明轮子的,你应该认真考虑考虑看看...
- 计时框架 -这是基地的动画框架,即不作任何你可能想如何使用它的假设。
- 三叉戟 -到计时框架类似,但也有基于Swing组件的支持(通过反射)建立
- 通用吐温引擎
此公因式分解例如容易承认下面的变化。 它利用所述封闭板的优选尺寸在JLayeredPane
。
/**
* @see https://stackoverflow.com/a/16322007/230513
* @see https://stackoverflow.com/a/16316345/230513
*/
public class TestPane extends JLayeredPane {
private static final int WIDE = 200;
private static final int HIGH = 5 * WIDE / 8; // ~1/phi
private JPanel panel;
public TestPane() {
panel = new JPanel();
panel.setBackground(Color.RED);
panel.add(new JButton("Test"));
add(panel);
Dimension size = panel.getPreferredSize();
int half = HIGH / 2 - size.height / 2;
Rectangle from = new Rectangle(size);
from.translate(WIDE, half);
Rectangle to = new Rectangle(size);
to.translate(0, half);
panel.setBounds(from);
Animate animate = new Animate(panel, from, to);
animate.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(WIDE, HIGH);
}
}
有一些在OP代码的问题。 如MadProrammer分,只应移动每计时器滴答一个步骤。 下面是一个简单,测试校正到OPS代码即一次移动的JPanel一个像素,25次。 需要注意的评论:
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 runs 25 times per second
timer = new Timer(40, new ActionListener() {
public void actionPerformed(ActionEvent ae) {
// Must 'remember' where we have slid panel to by using instance variable rather than automatic variable
// Only move one step at a time.
// No need to restart timer, it continues to run until stopped
if (xFrom > xTo){
xFrom = xFrom - 1;
panel.setLocation(xFrom, y);
panel.repaint();
} else {
timer.stop();
}
panel.setLocation(xFrom, y);
panel.repaint();
}
});
timer.start();
}
例如任何滑动
package TestingPackage;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class ToggleBtn extends JPanel {
JFrame frame;
JPanel panelOut;
JLabel labelOn;
JLabel labelOff;
JButton btn;
int count = 1;
public ToggleBtn() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(500, 300, 300, 300);
frame.setLayout(null);
panelOut = new JPanel(null);
panelOut.setBounds(50, 100, 120, 30);
panelOut.setBackground(Color.gray);
frame.add(panelOut);
btn = new JButton("::");
btn.setBounds(0, 0, 60, 30);
panelOut.add(btn);
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
startThread();
}
});
labelOn = new JLabel("ON");
labelOn.setBounds(0, 0, 60, 30);
panelOut.add(labelOn);
labelOff = new JLabel("OFF");
labelOff.setBounds(60, 0, 60, 30);
panelOut.add(labelOff);
frame.setVisible(true);
}
public void startThread() {
count++;
new Move().start();
}
public static void main(String[] args) {
new ToggleBtn();
}
class Move extends Thread {
@Override
public void run() {
if (count % 2 == 0) {
System.out.println("if");
for (int i = 0; i <= 60; i++) {
try {
Thread.sleep(3);
} catch (InterruptedException ex) {
Logger.getLogger(ToggleBtn.class.getName()).log(Level.SEVERE, null, ex);
}
btn.setBounds(i, 0, 60, 30);
}
} else {
System.out.println("else");
for (int i = 60; i >= 0; i--) {
try {
Thread.sleep(3);
} catch (InterruptedException ex) {
Logger.getLogger(ToggleBtn.class.getName()).log(Level.SEVERE, null, ex);
}
btn.setBounds(i, 0, 60, 30);
}
}
}
}
}