我目前正在学习NetBeans中的Java动画和图形。
我决定在JPanel开始一个简单的球运动。
我在修复闪烁的闪烁问题时遇到了一些问题。我看了很多论坛,但大多数是使用Double Buffering的AWT,但我知道SWING组件不需要Double Buffering。我尝试过 - 使用repaint()
和。clearRect()
。
在2中我发现使用。clearRect()
给了我更好的结果,但不是无缝无闪动的动画。所以我想知道是否有更好的方法来消除闪烁。
这是我的代码:
public class NewJFrame extends javax.swing.JFrame {
int x;
int y;
int xspeed = 1;
int yspeed = 1;
int width;
int height;
Graphics g;
/**
* Creates new form NewJFrame
*/
public NewJFrame() {
initComponents();
}
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
g = jp.getGraphics();
width = jp.getWidth();
height = jp.getHeight();
final Timer timerCHK = new Timer();
timerCHK.schedule(new TimerTask() {
public void run() {
move();
time();
}
}, 1000, 10);
}
void time() {
final Graphics g = jp.getGraphics();
final Timer timerCHK = new Timer();
timerCHK.schedule(new TimerTask() {
public void run() {
g.clearRect(0, 0, jp.getWidth() - 3, jp.getHeight() - 3);
}
}, 1000, 12);
}
void move() {
x = x + xspeed;
y = y + yspeed;
Graphics mk = jp.getGraphics();
if (x < 0) {
x = 0;
xspeed = -xspeed;
} else if (x > width - 20) {
x = width - 20;
xspeed = -xspeed;
}
if (y < 0) {
y = 0;
yspeed = -yspeed;
} else if (y == height - 20) {
y = height - 20;
yspeed = -yspeed;
}
mk.drawOval(x, y, 20, 20);
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new NewJFrame().setVisible(true);
}
});
}
}
答案 0 :(得分:2)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class NewJFrame extends JFrame {
private JPanel jp;
private Timer timer;
public NewJFrame() {
initComponents();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
this.setLocationByPlatform(true);
timer.start();
}
public void initComponents() {
ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
jp.repaint();
}
};
timer = new Timer(50,al);
jp = new JPanel() {
int x;
int y;
int xspeed = 1;
int yspeed = 1;
Dimension preferredSize = new Dimension(300, 100);
@Override
public Dimension getPreferredSize() {
return preferredSize;
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
this.move();
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.drawOval(x, y, 20, 20);
}
void move() {
x = x + xspeed;
y = y + yspeed;
if (x < 0) {
x = 0;
xspeed = -xspeed;
} else if (x > getWidth() - 20) {
x = getWidth() - 20;
xspeed = -xspeed;
}
if (y < 0) {
y = 0;
yspeed = -yspeed;
} else if (y == getHeight() - 20) {
y = getHeight() - 20;
yspeed = -yspeed;
}
}
};
jp.setBackground(Color.ORANGE);
this.add(jp);
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new NewJFrame().setVisible(true);
}
});
}
}
答案 1 :(得分:0)
这不是答案(本身),而是延伸评论 - 评论没有足够的空间
我想了解更多。可以建议一些基础教程 开始的动画(就像你提到的例子一样)?
不幸的是,不是。几年前我做了一个简短的3D动画课程,并将其中的许多基本原理应用到我的编程中。虽然许多理论对我们所做的事情都是多余的,但它们仍然很重要。
您将面临的问题不仅是您需要对动画理论有一个很好的理解,而且还需要很好地理解Swing的内部工作原理和API。
在这方面,有许多优秀的API可以帮助您,但您仍然需要了解动画理论,以便将它们用于盗版。
Kirill Grouchnikov在他的Pushing Pixels网站上做了一些优秀的帖子(以支持他的Trident animation引擎),这可能是两个学科之间的合适妥协。
基里尔还强调了以下艺术品(我不得不承认,我还没读过......但是))
使用Swing side更新
对于Swing方面的事情,你需要对...有很好的理解。
在秋千中绘画 - 请查看Painting in AWT and Swing和Performing Custom Painting。
这真的非常重要。这是开发人员第一次开始尝试在Swing中执行动画时最常见的误解之一。
您还需要了解Concurrency in Java,尤其是它如何适用于Swing
答案 2 :(得分:-1)
我有一个非常类似的闪烁问题,我用了
contentPane.updateUI();
并解决了我所有的问题 如果updateUI()解决了您的问题,请告诉我