我在java中制作一系列图像。到目前为止,我能够毫无问题地制作动画。只有当我添加控件(开始,停止等)时才会出现问题。当我在GUI中按“开始”时,GUI不会显示动画,只有在动画结束后才会显示最后一帧。
我不确定它是线程问题还是绘画问题,因为我尝试了一些方法而且没有一个方法有效。
以下是我的代码:
public class SwingAnimation extends JPanel implements ActionListener {
protected JFrame frame;
protected JLabel lblDisplay;
protected JButton BtnStart, BtnStop, BtnPause;
protected JCheckBox chkLoop;
protected Thread th;
public static void main(String[] args) {
SwingAnimation sa = new SwingAnimation();
}
public SwingAnimation() {
frame = new JFrame("Animation");
Panel panel = new Panel();
lblDisplay = new JLabel();
BtnStart = new JButton("Start");
BtnStop = new JButton("Stop");
BtnPause = new JButton("Pause");
chkLoop = new JCheckBox("Loop");
BtnStop.setEnabled(false);
BtnPause.setEnabled(false);
BtnStart.setActionCommand("start");
BtnStop.setActionCommand("stop");
BtnPause.setActionCommand("pause");
panel.add(lblDisplay);
panel.add(BtnStart);
panel.add(BtnPause);
panel.add(BtnStop);
panel.add(chkLoop);
frame.add(panel, BorderLayout.CENTER);
frame.setSize(400, 400);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//set the frame in the center of the screen
Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize();
int screen_x = (screensize.width - frame.getWidth()) / 2;
int screen_y = (screensize.height - frame.getHeight()) / 2;
frame.setLocation(screen_x, screen_y);
BtnStart.addActionListener(this);
BtnStop.addActionListener(this);
BtnPause.addActionListener(this);
chkLoop.addActionListener(this);
th = new Thread();
//ImageAnimator();
}
public void ImageAnimator() {
try {
for (int i = 0; i <= 299; i++) {
ImageIcon images = new ImageIcon("C:\\Users\\Desktop\\Images\\Snap" + i + ".jpg");
lblDisplay.setIcon(images);
th.sleep(25);
}
} catch (InterruptedException e) {
}
}
public void actionPerformed(ActionEvent e) {
if ("start".equals(e.getActionCommand())) {
BtnStart.setEnabled(false);
BtnStop.setEnabled(true);
BtnPause.setEnabled(true);
lblDisplay.setVisible(true);
ImageAnimator();
} else if ("stop".equals(e.getActionCommand())) {
BtnStart.setText("Start");
BtnStart.setEnabled(true);
BtnStop.setEnabled(false);
BtnPause.setEnabled(false);
lblDisplay.setVisible(false);
th = null;
} else if ("pause".equals(e.getActionCommand())) {
BtnStart.setText("Resume");
BtnStart.setEnabled(true);
BtnStop.setEnabled(true);
BtnPause.setEnabled(false);
}
}
protected JFrame frame;
protected JLabel lblDisplay;
protected JButton BtnStart, BtnStop, BtnPause;
protected JCheckBox chkLoop;
protected Thread th;
public static void main(String[] args) {
SwingAnimation sa = new SwingAnimation();
}
public SwingAnimation() {
frame = new JFrame("Animation");
Panel panel = new Panel();
lblDisplay = new JLabel();
BtnStart = new JButton("Start");
BtnStop = new JButton("Stop");
BtnPause = new JButton("Pause");
chkLoop = new JCheckBox("Loop");
BtnStop.setEnabled(false);
BtnPause.setEnabled(false);
BtnStart.setActionCommand("start");
BtnStop.setActionCommand("stop");
BtnPause.setActionCommand("pause");
panel.add(lblDisplay);
panel.add(BtnStart);
panel.add(BtnPause);
panel.add(BtnStop);
panel.add(chkLoop);
frame.add(panel, BorderLayout.CENTER);
frame.setSize(400, 400);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//set the frame in the center of the screen
Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize();
int screen_x = (screensize.width - frame.getWidth()) / 2;
int screen_y = (screensize.height - frame.getHeight()) / 2;
frame.setLocation(screen_x, screen_y);
BtnStart.addActionListener(this);
BtnStop.addActionListener(this);
BtnPause.addActionListener(this);
chkLoop.addActionListener(this);
th = new Thread();
//ImageAnimator();
}
public void ImageAnimator() {
try {
for (int i = 0; i <= 299; i++) {
ImageIcon images = new ImageIcon("C:\\Users\\Desktop\\Images\\Snap" + i + ".jpg");
lblDisplay.setIcon(images);
th.sleep(25);
}
} catch (InterruptedException e) {
}
}
public void actionPerformed(ActionEvent e) {
if ("start".equals(e.getActionCommand())) {
BtnStart.setEnabled(false);
BtnStop.setEnabled(true);
BtnPause.setEnabled(true);
lblDisplay.setVisible(true);
ImageAnimator();
} else if ("stop".equals(e.getActionCommand())) {
BtnStart.setText("Start");
BtnStart.setEnabled(true);
BtnStop.setEnabled(false);
BtnPause.setEnabled(false);
lblDisplay.setVisible(false);
th = null;
} else if ("pause".equals(e.getActionCommand())) {
BtnStart.setText("Resume");
BtnStart.setEnabled(true);
BtnStop.setEnabled(true);
BtnPause.setEnabled(false);
}
}
答案 0 :(得分:3)
快速修复:
像这样更改ImageAnimator():
lblDisplay.setIcon(images);
lblDisplay.paintImmediately(getBounds());
th.sleep(25);
您遇到的问题是设置图标不会自动导致Swing重新绘制屏幕上的组件。立即调用paint会做到这一点。
一般建议:
摆动动画通常使用Swing Timer完成。你会注意到你的UI没有响应 - 一旦你开始动画,你将无法阻止它直到它结束。那是因为所有Swing事件都发生在一个线程上 - 事件调度线程。在中间运行一个带有Thread.sleep(...)的循环将该线程绑定,使其无法处理其他输入(例如按下停止按钮)
当我试图理解Swing如何处理并发时,This article帮助了我,The Swing Trail有很多关于有效使用Swing,绘制自定义组件等方面的建议。
我还会在Filthy Rich Clients上插入演示代码,我现在正在阅读这本书,值得一看。
答案 1 :(得分:1)
这个Java 2D games tutorial涵盖了几种基本的动画技术。我们引用了一些说明这些技术的相关示例here,这个完整的example说明了停止和启动按钮。