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();
}
}
}