Java Swing: how to smoothly animate/move component

2019-01-26 18:09发布

问题:

I am trying to figure out how to animate a swing component to go from point a to point b. Here is a baby example of code which makes a red JPanel move from left to right :


import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class MovingSquareExample {

    private static final JPanel square = new JPanel();
    private static int x = 20;

    public static void createAndShowGUI(){
        JFrame frame = new JFrame();
        frame.getContentPane().setLayout(null);
        frame.setSize(500,500);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(square);
        square.setBounds(20,200,100,100);
        square.setBackground(Color.RED);

        Timer timer = new Timer(1000/60,new MyActionListener());
        timer.start();
        frame.setVisible(true);
    }

    public static class MyActionListener implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent arg0) {
            square.setLocation(x++, 200);

        }

    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run(){
                createAndShowGUI();

            }
        });


    }

}

It works fine, it's just that I looks a little choppy. The motion for the analogous example with a draggable square (see Draggable Components in Java Swing) appears much smoother so I believe there should be a way to make this look better. Any suggestions would be much appreciated.

回答1:

You are entering a tricky area for the Swing library. However, nothing is impossible. You can create such animation using Timer, but I really recommend you do not do it. So you can move components as best as possible, I suggest you make use of the Timing Framework library.

But be aware: Move components is not something that should be made without study. Swing layouts were developed so that the components are placed in a specific order. If you manipulate the values ​​of dimensions and positioning of components, you will be breaking the functionality of the layouts, and your program is likely to behave in strange ways. I've had cases where I developed an application in Swing without the use of layout. In an operating system, my program seemed to work properly, but porting it to other systems, everything went into disarray. Therefore, you need to stay tuned and perform many tests before launching an application in Swing that has such customizations.

This was one reason that the JavaFX technology came into our hands. With such technology, we can concern ourselves with less stuff (deploy the application in different programs) and do much more (including the one you're having trouble). Consider migrating to this technology. So you see what JavaFX can do, download the demo program Ensemble (Search for "JavaFX Demos and Samples Downloads"). As a source of study, start here.

If this alternative is too laborious for you, check out the link I gave you about the Timing Framework library. There you will find examples of Java code that make smooth animations on various Swing things with a high performance. To learn how to use this library, I suggest you to get the book Filthy Rich Clients, written by Chet Haase and Romain Guy. Although the book is out of date and things have been changed in the library code, you can get updated on the library website. As I said earlier, download the library, and also download the code samples. With time, you will end up doing what you want in the best possible way.

I hope you can accomplish what you want. Good luck. :)