我有一个输出模式的小程序。我希望看到实时绘制的线条,而不是像我一样只看到最终程序的输出。我的最终结果将是产生一个实时的万花筒效果。我该怎么做?(只是实时位(
谢谢。
public void paintComponent(Graphics myPen) {
super.paintComponent(myPen);
myPen.setColor(Color.red);
int increment = 1;
int count = 0;
while (count < 5) {
int x = 0;
int y = 0;
while (x < 400)
{
myPen.drawLine(200, 200, x, y);
x = x + increment;
}
while (y < 400) {
myPen.drawLine(200, 200, x, y);
y = y + increment;
}
while (x > 0) {
myPen.drawLine(200, 200, x, y);
x = x - increment;
}
while (y > 0) {
myPen.drawLine(200, 200, x, y);
y = y - increment;
}
if (count == 1) {
myPen.setColor(Color.blue);
}
if (count == 2) {
myPen.setColor(Color.green);
}
if (count == 3) {
myPen.setColor(Color.white);
}
if (count == 4) {
myPen.setColor(Color.magenta);
}
if (count == 5) {
myPen.setColor(Color.yellow);
}
increment++;
count++;
}
}
}
您要做的是动画GUI绘图,并逐步更新图像。解决这个需要几个步骤
- 使用动画或"游戏"循环来驱动动画,这是使用Swing Timer最容易实现的
- 在动画循环中,绘制BufferedImage,并调用
repaint()
- 使用
Graphics#drawImage(...)
方法在paintComponent方法中绘制该图像
简单示例:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class SimpleAnimation extends JPanel {
private static final int IMG_W = 800;
private static final int IMG_H = IMG_W;
private static final int TIMER_DELAY = 40;
public static final Stroke STROKE = new BasicStroke(6f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
public static final Color DRAW_COLOR = Color.RED;
public static final double DELTA = 8;
private BufferedImage img = new BufferedImage(IMG_W, IMG_H, BufferedImage.TYPE_INT_ARGB);
private Timer animationTimer = null;
private int myX = 0;
private int myY = 0;
public SimpleAnimation() {
setBackground(Color.WHITE);
JButton drawButton = new JButton("Draw!");
drawButton.addActionListener(e -> draw());
add(drawButton);
}
private void draw() {
// if timer currently running, stop it
if (animationTimer != null && animationTimer.isRunning()) {
animationTimer.stop();
}
myX = 0;
myY = 0;
img = new BufferedImage(IMG_W, IMG_H, BufferedImage.TYPE_INT_ARGB);
animationTimer = new Timer(TIMER_DELAY, new TimerListener());
animationTimer.start();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, 0, 0, this);
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(IMG_W, IMG_H);
}
private class TimerListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (img == null) {
return;
}
Graphics2D g2 = img.createGraphics();
g2.setStroke(STROKE);
g2.setColor(DRAW_COLOR);
int x = myX + (int) (DELTA * Math.random());
int y = myY + (int) (DELTA * Math.random());
g2.drawLine(x, y, myX, myY);
g2.dispose();
myX = x;
myY = y;
if (myX > IMG_W || myY > IMG_H) {
((Timer) e.getSource()).stop();
}
repaint();
}
}
private static void createAndShowGui() {
SimpleAnimation mainPanel = new SimpleAnimation();
JFrame frame = new JFrame("SimpleAnimation");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}