Java Swing动画优化

Java Swing动画优化,java,swing,animation,java-2d,Java,Swing,Animation,Java 2d,我一直在使用JComponent上的Timer制作一个简单的动画。然而,当我观看动画时,我会体验到令人难以置信的起伏运动。我应该采取什么步骤来优化此代码 MyAnimationFrame AnimationComponent import javax.swing.*; 导入java.awt.*; 公共类AnimationComponent扩展JComponent实现ActionListener{ 私人定时器; 私人INTX; 私营企业; 私人int xVel; 伊维尔私人酒店; 私有整数宽度;

我一直在使用
JComponent
上的
Timer
制作一个简单的动画。然而,当我观看动画时,我会体验到令人难以置信的起伏运动。我应该采取什么步骤来优化此代码

MyAnimationFrame
AnimationComponent
import javax.swing.*;
导入java.awt.*;
公共类AnimationComponent扩展JComponent实现ActionListener{
私人定时器;
私人INTX;
私营企业;
私人int xVel;
伊维尔私人酒店;
私有整数宽度;
私人内部高度;
私有int oldX;
私家侦探;
公共动画组件(整数x、整数y、整数宽度、整数高度){
这个.x=x;
这个。y=y;
高度=高度;
这个。宽度=宽度;
animTimer=新计时器(25,此);
xVel=5;
yVel=5;
animTimer.start();
}
@凌驾
公共组件(图形g){
g、 圆角(x,y,宽度,高度);
}
@凌驾
已执行的公共无效操作(操作事件e){
oldX=x;
oldY=y;
如果(x+width>getParent().getWidth()|| x<0){
xVel*=-1;
}
如果(y+height>getParent().getHeight()| | y<0){
yVel*=-1;
}
x+=xVel;
y+=yVel;
重新油漆();
}
}
不确定这是否重要,但我使用的是OpenJDK版本1.8.0_121

非常感谢您的帮助。

提供了一种提供高度优化动画的方法,在这种情况下可能会有所帮助

MyAnimationFrame

import javax.swing.*;

public class MyAnimationFrame extends JFrame {
    public MyAnimationFrame() {
        super("My animation frame!");
        setSize(300,300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        add(new AnimationComponent(0,0,50,50));
        setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                MyAnimationFrame f = new MyAnimationFrame();
            }
        });
    }
}
动画组件

import java.awt.*;
import java.awt.event.*;
import java.util.concurrent.TimeUnit;
import org.jdesktop.core.animation.rendering.*;
import org.jdesktop.core.animation.timing.*;
import org.jdesktop.core.animation.timing.interpolators.*;
import org.jdesktop.swing.animation.rendering.*;
import org.jdesktop.swing.animation.timing.sources.*;

@SuppressWarnings("serial")
public class AnimationComponent extends JRendererPanel {

    protected int x;
    protected int y;
    protected int width;
    protected int height;
    protected Animator xAnimator;
    protected Animator yAnimator;

    public AnimationComponent(int x, int y, int width, int height) {
        setOpaque(true);

        this.x = x;
        this.y = y;
        this.height = height;
        this.width = width;

        JRendererFactory.getDefaultRenderer(this,
                new JRendererTarget<GraphicsConfiguration, Graphics2D>() {
            @Override
            public void renderSetup(GraphicsConfiguration gc) {
                // Nothing to do
            }
            @Override
            public void renderUpdate() {
              // Nothing to do
            }
            @Override
            public void render(Graphics2D g, int w, int h) {
                Color c = g.getColor();
                g.setColor(g.getBackground());
                g.fillRect(0, 0, w, h);
                g.setColor(c);
                g.fillOval(AnimationComponent.this.x, AnimationComponent.this.y,
                        AnimationComponent.this.width, AnimationComponent.this.height);
            }
            @Override
            public void renderShutdown() {
              // Nothing to do
            }
        }, false);

        this.xAnimator = new Animator.Builder(new SwingTimerTimingSource())
                .addTargets(new TimingTargetAdapter() {
                    @Override
                    public void timingEvent(Animator source, double fraction) {
                        AnimationComponent.this.x = (int) ((getWidth() - AnimationComponent.this.width) * fraction);
                    }})
                .setRepeatCount(Animator.INFINITE)
                .setRepeatBehavior(Animator.RepeatBehavior.REVERSE)
                .setInterpolator(LinearInterpolator.getInstance()).build();

        this.yAnimator = new Animator.Builder(new SwingTimerTimingSource())
                .addTargets(new TimingTargetAdapter() {
                    @Override
                    public void timingEvent(Animator source, double fraction) {
                        AnimationComponent.this.y = (int) ((getHeight() - AnimationComponent.this.height) * fraction);
                    }})
                .setRepeatCount(Animator.INFINITE)
                .setRepeatBehavior(Animator.RepeatBehavior.REVERSE)
                .setInterpolator(LinearInterpolator.getInstance()).build();

        addComponentListener(new ComponentAdapter() {
            private int oldWidth = 0;
            private int oldHeight = 0;
            @Override
            public void componentResized(ComponentEvent event) {
                Component c = event.getComponent();
                int w = c.getWidth();
                int h = c.getHeight();

                if (w != this.oldWidth) {
                    AnimationComponent.this.xAnimator.stop();
                    AnimationComponent.this.xAnimator = new Animator.Builder()
                            .copy(AnimationComponent.this.xAnimator)
                            .setDuration(w * 5, TimeUnit.MILLISECONDS) // Original speed was 200 px/s
                            .build();
                    AnimationComponent.this.xAnimator.start();
                }
                if (h != this.oldHeight) {
                    AnimationComponent.this.yAnimator.stop();
                    AnimationComponent.this.yAnimator = new Animator.Builder()
                            .copy(AnimationComponent.this.yAnimator)
                            .setDuration(h * 5, TimeUnit.MILLISECONDS) // Original speed was 200 px/s
                            .build();
                    AnimationComponent.this.yAnimator.start();
                }

                this.oldWidth = w;
                this.oldHeight = h;
            }
        });
    }

}
import java.awt.*;
导入java.awt.event.*;
导入java.util.concurrent.TimeUnit;
导入org.jdesktop.core.animation.rendering.*;
导入org.jdesktop.core.animation.timing.*;
导入org.jdesktop.core.animation.timening.interpolators.*;
导入org.jdesktop.swing.animation.rendering.*;
导入org.jdesktop.swing.animation.timing.sources.*;
@抑制警告(“串行”)
公共类AnimationComponent扩展JrenderPanel{
受保护的int x;
保护智力;
保护整数宽度;
保护内部高度;
受保护动画师xAnimator;
受保护动画师yAnimator;
公共动画组件(整数x、整数y、整数宽度、整数高度){
set不透明(true);
这个.x=x;
这个。y=y;
高度=高度;
这个。宽度=宽度;
JRendererFactory.getDefaultRenderer(此,
新JrenderTarget(){
@凌驾
公共void renderSetup(图形配置gc){
//无事可做
}
@凌驾
公共无效renderUpdate(){
//无事可做
}
@凌驾
公共无效渲染(图形2D g、int w、int h){
颜色c=g.getColor();
g、 setColor(g.getBackground());
g、 fillRect(0,0,w,h);
g、 setColor(c);
g、 Fillova(AnimationComponent.this.x,AnimationComponent.this.y,
AnimationComponent.this.width、AnimationComponent.this.height);
}
@凌驾
public void renderShutdown(){
//无事可做
}
},假);
this.xAnimator=new Animator.Builder(new SwingTimerTimingSource())
.addTargets(新计时目标适配器(){
@凌驾
公共void timingEvent(动画师源,双分数){
AnimationComponent.this.x=(int)((getWidth()-AnimationComponent.this.width)*分数);
}})
.setRepeatCount(Animator.INFINITE)
.setRepeatBehavior(Animator.RepeatBehavior.REVERSE)
.setInterpolator(LinearInterpolator.getInstance()).build();
this.yAnimator=new Animator.Builder(new SwingTimerTimingSource())
.addTargets(新计时目标适配器(){
@凌驾
公共void timingEvent(动画师源,双分数){
AnimationComponent.this.y=(int)((getHeight()-AnimationComponent.this.height)*分数);
}})
.setRepeatCount(Animator.INFINITE)
.setRepeatBehavior(Animator.RepeatBehavior.REVERSE)
.setInterpolator(LinearInterpolator.getInstance()).build();
addComponentListener(新的ComponentAdapter(){
私有int oldWidth=0;
私有整数oldHeight=0;
@凌驾
public void ComponentResistized(ComponentEvent事件){
组件c=event.getComponent();
int w=c.getWidth();
int h=c.getHeight();
如果(w!=此.oldWidth){
AnimationComponent.this.xAnimator.stop();
AnimationComponent.this.xAnimator=新的Animator.Builder()
.copy(AnimationComponent.this.xAnimator)
.setDuration(w*5,时间单位为毫秒)//原始速度为200 px/s
.build();
AnimationComponent.this.xAnimator.start();
}
如果(h!=此.oldHeight){
AnimationComponent.this.yAnimator.stop();
AnimationComponent.this.yAnimator=新建Animator.Builder()
.copy(AnimationComponent.this.yAnimator)
.setDuration(h*5,时间单位为毫秒)//原始速度为200 px/s
.build();
AnimationComponent.this.yAnimator.start();
}
这个.oldWidth=w;
该高度=h;
}
});
}
}
我得到了很好的效果,但有一个问题:任何你调整大小的项目,动画都会被重置。

提供
import javax.swing.*;

public class MyAnimationFrame extends JFrame {
    public MyAnimationFrame() {
        super("My animation frame!");
        setSize(300,300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        add(new AnimationComponent(0,0,50,50));
        setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                MyAnimationFrame f = new MyAnimationFrame();
            }
        });
    }
}
import java.awt.*;
import java.awt.event.*;
import java.util.concurrent.TimeUnit;
import org.jdesktop.core.animation.rendering.*;
import org.jdesktop.core.animation.timing.*;
import org.jdesktop.core.animation.timing.interpolators.*;
import org.jdesktop.swing.animation.rendering.*;
import org.jdesktop.swing.animation.timing.sources.*;

@SuppressWarnings("serial")
public class AnimationComponent extends JRendererPanel {

    protected int x;
    protected int y;
    protected int width;
    protected int height;
    protected Animator xAnimator;
    protected Animator yAnimator;

    public AnimationComponent(int x, int y, int width, int height) {
        setOpaque(true);

        this.x = x;
        this.y = y;
        this.height = height;
        this.width = width;

        JRendererFactory.getDefaultRenderer(this,
                new JRendererTarget<GraphicsConfiguration, Graphics2D>() {
            @Override
            public void renderSetup(GraphicsConfiguration gc) {
                // Nothing to do
            }
            @Override
            public void renderUpdate() {
              // Nothing to do
            }
            @Override
            public void render(Graphics2D g, int w, int h) {
                Color c = g.getColor();
                g.setColor(g.getBackground());
                g.fillRect(0, 0, w, h);
                g.setColor(c);
                g.fillOval(AnimationComponent.this.x, AnimationComponent.this.y,
                        AnimationComponent.this.width, AnimationComponent.this.height);
            }
            @Override
            public void renderShutdown() {
              // Nothing to do
            }
        }, false);

        this.xAnimator = new Animator.Builder(new SwingTimerTimingSource())
                .addTargets(new TimingTargetAdapter() {
                    @Override
                    public void timingEvent(Animator source, double fraction) {
                        AnimationComponent.this.x = (int) ((getWidth() - AnimationComponent.this.width) * fraction);
                    }})
                .setRepeatCount(Animator.INFINITE)
                .setRepeatBehavior(Animator.RepeatBehavior.REVERSE)
                .setInterpolator(LinearInterpolator.getInstance()).build();

        this.yAnimator = new Animator.Builder(new SwingTimerTimingSource())
                .addTargets(new TimingTargetAdapter() {
                    @Override
                    public void timingEvent(Animator source, double fraction) {
                        AnimationComponent.this.y = (int) ((getHeight() - AnimationComponent.this.height) * fraction);
                    }})
                .setRepeatCount(Animator.INFINITE)
                .setRepeatBehavior(Animator.RepeatBehavior.REVERSE)
                .setInterpolator(LinearInterpolator.getInstance()).build();

        addComponentListener(new ComponentAdapter() {
            private int oldWidth = 0;
            private int oldHeight = 0;
            @Override
            public void componentResized(ComponentEvent event) {
                Component c = event.getComponent();
                int w = c.getWidth();
                int h = c.getHeight();

                if (w != this.oldWidth) {
                    AnimationComponent.this.xAnimator.stop();
                    AnimationComponent.this.xAnimator = new Animator.Builder()
                            .copy(AnimationComponent.this.xAnimator)
                            .setDuration(w * 5, TimeUnit.MILLISECONDS) // Original speed was 200 px/s
                            .build();
                    AnimationComponent.this.xAnimator.start();
                }
                if (h != this.oldHeight) {
                    AnimationComponent.this.yAnimator.stop();
                    AnimationComponent.this.yAnimator = new Animator.Builder()
                            .copy(AnimationComponent.this.yAnimator)
                            .setDuration(h * 5, TimeUnit.MILLISECONDS) // Original speed was 200 px/s
                            .build();
                    AnimationComponent.this.yAnimator.start();
                }

                this.oldWidth = w;
                this.oldHeight = h;
            }
        });
    }

}
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame("Test");
                frame.add(new AnimationComponent(0, 0, 50, 50));
                frame.setSize(300, 300);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class AnimationComponent extends JComponent implements ActionListener {

        private Timer animTimer;
        private int x;
        private int y;
        private int xVel;
        private int yVel;
        private int width;
        private int height;
        private int oldX;
        private int oldY;

        public AnimationComponent(int x, int y, int width, int height) {
            this.x = x;
            this.y = y;
            this.height = height;
            this.width = width;

            animTimer = new Timer(5, this);
            xVel = 1;
            yVel = 1;

            animTimer.start();
        }

        @Override
        public void paintComponent(Graphics g) {
            Graphics2D g2d = (Graphics2D) g.create();
            RenderingHints hints = new RenderingHints(
                    RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON
            );
            g2d.setRenderingHints(hints);
            g2d.fillOval(x, y, width, height);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            oldX = x;
            oldY = y;

            if (x + width > getParent().getWidth() || x < 0) {
                xVel *= -1;
            }

            if (y + height > getParent().getHeight() || y < 0) {
                yVel *= -1;
            }

            x += xVel;
            y += yVel;

            repaint();
        }
    }
}