Java:Swing的安全动画

Jim*_*uch 5 java animation swing jframe

我正在创建一个使用JFrame,JPanel,JLabel和所有其他类型的swing组件的程序.

我想要做的是在专用于此动画的单独JPanel上创建2D动画.所以我将覆盖paintComponent(Graphics g)方法.

我有使用for循环+线程制作动画的经验,但我听说线程在摆动时并不安全.

因此,使用Runnable接口制作动画是否安全?如果不是我应该使用什么(例如计时器),请举例说明如何最好地使用它(或链接到网页).

编辑:

感谢Jeff,我将使用Timer来创建动画.对于这个问题的未来观众,这是一个我在大约5分钟内编写的快速程序,原谅脏代码.

我还添加了一些快速评论.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


class JFrameAnimation extends JFrame implements ActionListener
{

    JPanel panel;
    Timer timer;
    int x, y;

    public JFrameAnimation ()
    {
        super ();
        setDefaultCloseOperation (EXIT_ON_CLOSE);
        timer = new Timer (15, this); //@ First param is the delay (in milliseconds) therefore this animation is updated every 15 ms. The shorter the delay, the faster the animation.
        //This class iplements ActionListener, and that is where the animation variables are updated. Timer passes an ActionEvent after each 15 ms.

    }


    public void run ()
    {

        panel = new JPanel ()
        {
            public void paintComponent (Graphics g)  //The JPanel paint method we are overriding.
            {
                g.setColor (Color.white);
                g.fillRect (0, 0, 500, 500); //Setting panel background (white in this case);
                //g.fillRect (-1 + x, -1 + y, 50, 50);  //This is to erase the black remains of the animation. (not used because the background is always redrawn.
                g.setColor (Color.black);
                g.fillRect (0 + x, 0 + y, 50, 50); //This is the animation.

            }

        }
        ;
        panel.setPreferredSize (new Dimension (500, 500)); //Setting the panel size

        getContentPane ().add (panel); //Adding panel to frame.
        pack ();
        setVisible (true);
        timer.start (); //This starts the animation.
    }


    public void actionPerformed (ActionEvent e)
    {
        x++;
        y++;
        if (x == 250)
            timer.stop (); //This stops the animation once it reaches a certain distance.
        panel.repaint ();  //This is what paints the animation again (IMPORTANT: won't work without this).
        panel.revalidate (); //This isn't necessary, I like having it just in case.

    }


    public static void main (String[] args)
    {
        new JFrameAnimation ().run (); //Start our new application.
    }
}
Run Code Online (Sandbox Code Playgroud)

Jef*_*rey 8

吉米,我认为你误解了线程如何在Swing中运行.您必须使用一个名为Event Dispatch Thread的特定线程来对swing组件进行任何更新(有一些特殊的例外,我将不在这里讨论).您可以使用swing计时器设置在事件派发线程上运行的定期任务.请参阅此示例,了解如何使用Swing计时器.http://download.oracle.com/javase/tutorial/uiswing/misc/timer.html

您还应该阅读Event Dispatch Thread,以便了解它在Swing中的位置http://download.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html

Java也提供了多种方法用于与Swing合作的SwingUtilities类,特别是invokeLaterinvokeAndWait这将运行事件调度线程上的代码.

  • +1,对Swing组件的所有更新必须在EDT上完成. (2认同)