Java: безопасная анимация с помощью Swing - PullRequest
5 голосов
/ 08 июня 2011

Я создаю программу, которая использует JFrame, JPanel, JLabel и все другие виды компонентов Swing.

Я хочу создать 2D-анимацию на отдельном JPanel, который посвящен этой анимации.Поэтому я буду переопределять метод paintComponent (Graphics g).

У меня есть опыт создания анимации с помощью циклов for + Threads, но я слышал, что потоки не безопасны при свинге.

Из-за этого безопасно ли мне создавать анимацию с помощьюиспользование интерфейса Runnable?Если не то, что я буду использовать (например, Таймер), и, пожалуйста, приведите небольшой пример того, как лучше всего его использовать (или ссылку на веб-страницу).

РЕДАКТИРОВАТЬ:

Благодаря Джеффу,Я буду использовать Таймер для создания анимации.Для будущих читателей этого вопроса вот небольшая программа, которую я написал за 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.
    }
}

Ответы [ 2 ]

8 голосов
/ 08 июня 2011

Джимми, я думаю, вы неправильно понимаете, как работают потоки в Swing.Вы должны использовать определенный поток под названием Event Dispatch Thread, чтобы выполнить любое обновление компонентов Swing (за некоторыми конкретными исключениями, которые я не буду обсуждать здесь).Вы можете использовать таймер колебания, чтобы настроить повторяющуюся задачу для выполнения в потоке диспетчеризации событий.Посмотрите этот пример использования таймеров Swing.http://download.oracle.com/javase/tutorial/uiswing/misc/timer.html

Вы также должны прочитать о потоке рассылки событий, чтобы понять его место в Swing http://download.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html

Java также предоставляет множество методов для работы с Swing в SwingUtilities class, а именно invokeLater и invokeAndWait, которые будут запускать код в потоке диспетчеризации событий.

1 голос
/ 22 июня 2011

Хотя хорошо понимать EDT и SwingUtilities (каждый, кто делает Swing, должен это делать), если вы собираетесь делать много анимации, я бы порекомендовал использовать доступную главу TimingFramework. This will allow you to concentrate a little more on design and will give you a better control on "rate". Inherently the timing framework uses a Swing timer so the callbacks are on the EDT. Part of the Filthy-rich clients collection, the author made the .

Веселись!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...