JLabel animation in JPanel

ε祈祈猫儿з 提交于 2020-01-01 19:33:15

问题


After scratching around I found that it's best to implement a custom image component by extending a JLabel. So far that has worked great as I can add multiple "images" (jlabels without the layout breaking. I just have a question that I hope someone can answer for me.

  • I noticed that in order to animate JLabels across the screen I need to setlayout(null); and setbounds of the component and then to animate eventually setlocation(x,y);. Is this a best practice or a terrible way to animate a component? I plan on eventually making an animation class but I don't want to do so and end up having to chuck it.

I have included relevant code for a quick review check.

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JPanel;
import javax.swing.Timer;

public class GraphicsPanel extends JPanel  {
    private Timer timer;
    private long startTime = 0;
    private int numFrames = 0;
    private float fps = 0.0f;
    private int x = 0;

    GraphicsPanel() {
        final Entity ent1 = new Entity();
        ent1.setBounds(x, 0, ent1.getWidth(), ent1.getHeight());
        add(ent1);

        //ESSENTIAL
        setLayout(null);

        //GAMELOOP
        timer = new Timer(30, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                getFPS();
                incX();
                ent1.setLocation(x, 0);
                repaint();
            }
        });
        timer.start();
    }

    public void incX() { x++; }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g.create();
        g2.setClip(0, 0, getWidth(), getHeight());

        g2.setColor(Color.BLACK);
        g2.drawString("FPS: " + fps, 1, 15);
    }

    public void getFPS()
    {
        ++numFrames;
        if (startTime == 0) {
            startTime = System.currentTimeMillis();
        } else {
            long currentTime = System.currentTimeMillis();
            long delta = (currentTime - startTime);
            if (delta > 1000) {
                fps = (numFrames * 1000) / delta;
                numFrames = 0;
                startTime = currentTime;              
            }
        }
    }
}

Thank you!


回答1:


I noticed that in order to animate JLabels across the screen I need to setlayout(null); and setbounds of the component and then to animate eventually setlocation(x,y);. Is this a best practice or a terrible way to animate a component?

Well, this is not entirely true. You can just play with the location and the label will move around the screen. However, if you ever resize the frame or anything then the layout manager will be invoked and the label will be repositioned and the location defined by the layout manager which in the case of a FlowLayout will be the top/left of the panel. Animation will then continue from that location. So in reality, yes, this is exactly what you need to do.

I find it the easiest way to do animation since Swing will automatically repaint the "last" location of the component (to restore the background) as well as paint the new location of the component. This is all achieved by a single setLocation() method.

Some people like to do custom painting by drawing the image directly on the panel, but then you are responsible for clearing the old location of the image so the background is redrawn and then draw the image in the new location. I find this too much work.



来源:https://stackoverflow.com/questions/2467230/jlabel-animation-in-jpanel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!