很大程度上取決於您最終想達到的目標。
記住,動畫是運動的錯覺......
我改變
- 的
framesPerSecond
到60
這似乎已經幫助。
- 減小可打印區域的總高度
- 計算改變的面積並簡單地調用
repaint(Rectangle)
只傳入已更改的區域。
另一個問題是您的動畫在很短的時間內有很大的覆蓋面積。增加的時間量也將使其更流暢(或減少寬度和/或高度)
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ScratchSpace {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
AnimatedPanel panel = new AnimatedPanel();
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
panel.animate();
}
});
}
public static class AnimatedPanel extends JPanel {
private float progress = 0.0f; // a number between 0.0 and 1.0
public AnimatedPanel() {
setPreferredSize(new Dimension(800, 100));
}
public void animate() {
final int animationTime = 1000;
int framesPerSecond = 60;
int delay = 1000/framesPerSecond;
final long start = System.currentTimeMillis();
final Timer timer = new Timer(delay, null);
timer.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
final long now = System.currentTimeMillis();
final long elapsed = now - start;
int width = getWidth();
int height = getHeight();
int oldWidth = (int) (width * progress);
progress = (float) elapsed/animationTime;
int newWidth = (int) (width * progress);
repaint(new Rectangle(oldWidth, 0, newWidth - oldWidth, height));
if (elapsed >= animationTime) {
timer.stop();
}
}
});
timer.start();
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
int width = getWidth();
int progressWidth = (int) (width * progress);
g2d.setColor(Color.BLUE);
g2d.fillRect(0, 0, progressWidth, getHeight());
g2d.setColor(Color.RED);
g2d.fillRect(progressWidth, 0, width - progressWidth, getHeight());
}
}
}
Alternativly,你可以生成你自己的備份緩衝區和更新...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ScratchSpace {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
AnimatedPanel panel = new AnimatedPanel();
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
panel.animate();
}
});
}
public static class AnimatedPanel extends JPanel {
private float progress = 0.0f; // a number between 0.0 and 1.0
private BufferedImage buffer;
public AnimatedPanel() {
setPreferredSize(new Dimension(800, 600));
// setOpaque(true);
}
public void animate() {
final int animationTime = 1000;
int framesPerSecond = 60;
int delay = 1000/framesPerSecond;
final long start = System.currentTimeMillis();
final Timer timer = new Timer(delay, null);
timer.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
final long now = System.currentTimeMillis();
final long elapsed = now - start;
int width = getWidth();
progress = (float) elapsed/animationTime;
updateBuffer();
repaint();
if (elapsed >= animationTime) {
timer.stop();
}
}
});
timer.start();
}
@Override
public void invalidate() {
buffer = null;
updateBuffer();
super.invalidate();
}
protected void updateBuffer() {
if (getWidth() > 0 && getHeight() > 0) {
if (buffer == null) {
buffer = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
}
Graphics2D g2d = buffer.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
int width = getWidth();
int height = getHeight();
float progressWidth = width * progress;
g2d.setColor(Color.BLUE);
g2d.fill(new Rectangle2D.Float(0, 0, progressWidth, height));
g2d.setColor(Color.RED);
g2d.fill(new Rectangle2D.Float(progressWidth, 0, width - progressWidth, height));
g2d.dispose();
}
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
if (buffer != null) {
g2d.drawImage(buffer, 0, 0, this);
}
// int width = getWidth();
// int progressWidth = (int) (width * progress);
// g2d.setColor(Color.BLUE);
// g2d.fillRect(0, 0, progressWidth, getHeight());
// g2d.setColor(Color.RED);
// g2d.fillRect(progressWidth, 0, width - progressWidth, getHeight());
}
}
}
的你所擁有的主要問題基本上就是你想要繪製的區域大到你想要繪製的區域。
另一個或者
您可以創建一個BufferedImage
表示進度條和移動的最新進展。此更新將創建一個兼容的緩衝圖像,這將使我們更快地呈示
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ScratchSpace {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
AnimatedPanel panel = new AnimatedPanel();
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
panel.animate();
}
});
}
public static class AnimatedPanel extends JPanel {
private float progress = 0.0f; // a number between 0.0 and 1.0
private BufferedImage buffer;
public AnimatedPanel() {
setPreferredSize(new Dimension(800, 600));
// setOpaque(true);
}
public void animate() {
final int animationTime = 1000;
int framesPerSecond = 60;
int delay = 1000/framesPerSecond;
final long start = System.currentTimeMillis();
final Timer timer = new Timer(delay, null);
timer.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
final long now = System.currentTimeMillis();
final long elapsed = now - start;
progress = (float) elapsed/animationTime;
repaint();
if (elapsed >= animationTime) {
timer.stop();
}
}
});
timer.start();
}
@Override
public void invalidate() {
buffer = null;
updateBuffer();
super.invalidate();
}
protected void updateBuffer() {
if (getWidth() > 0 && getHeight() > 0) {
if (buffer == null) {
GraphicsConfiguration config = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
buffer = config.createCompatibleImage(getWidth(), getHeight(), Transparency.TRANSLUCENT);
buffer.coerceData(true);
Graphics2D g2d = buffer.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
int width = getWidth();
int height = getHeight();
g2d.setColor(Color.BLUE);
g2d.fill(new Rectangle2D.Float(0, 0, width, height));
g2d.dispose();
}
}
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
int width = getWidth();
int progressWidth = (int) (width * progress);
int x = (progressWidth - width);
System.out.println(progressWidth + "; " + x);
// g2d.setColor(Color.BLUE);
// g2d.fillRect(0, 0, progressWidth, getHeight());
g2d.setColor(Color.RED);
g2d.fillRect(progressWidth, 0, width - progressWidth, getHeight());
g2d.drawImage(buffer, x, 0, this);
}
}
}
爲的isDoubleBuffered()的值在JPanel的是真實的 – 2013-03-19 22:07:27
1)使用一個BufferedImage的背景圖像。 2)通過使用「repaint(...)'重載來限制重繪次數,該重載只重繪GUI的一個有限區域,僅用於您的目的。 3)玩你的幀率,看看什麼效果最好。 4)使用非Swing動畫/ GUI庫(如Slick)進行實驗,這可能會更好地針對動畫進行優化。 – 2013-03-19 22:23:36
縮小您正在繪製的區域的尺寸 – MadProgrammer 2013-03-19 22:26:14