动画一系列图像

时间:2009-12-16 09:00:03

标签: java

我在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); } }

2 个答案:

答案 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说明了停止和启动按钮。