【问题标题】:Stopping an animated DrawLine and starting a new one停止动画 DrawLine 并开始一个新的
【发布时间】:2015-03-21 12:27:40
【问题描述】:

编辑:这是完整的代码。在执行每个 actionPerformed 之后,我需要在执行 repain() 之前更改 x1、y1、x2、y2 和 t 的值。有没有一种简单的方法可以做到这一点?我只上过一门 Java 基础课,所以尽量保持在初级水平。

import java.awt.event.*;
import java.awt.*;
import javax.swing.*; 

public class Line {

  public static void main(String[] args) {
    java.awt.EventQueue.invokeLater(new Runnable() {
      public void run() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);;
        frame.add(new DrawLine(0,0,0,0));
        frame.setSize(500,500);
        frame.setVisible(true);  
      }
    });  
  } 
}

class DrawLine extends JPanel implements ActionListener {

  int x1;
  int y1;
  int x2;
  int y2;
  int i=100;
  int j=50;
  int t=1000;
  Timer time = new Timer(t, (ActionListener) this);

  public DrawLine(int x1, int y1, int x2, int y2) {
    this.x1 = x1;
    this.y1 = y1;
    this.x2 = x2;
    this.y2 = y2;
    time.start();
  }

  public void animateLine(Graphics2D g) {
    g.drawLine(x1,y1,x2,y2);
  }

  public void actionPerformed(ActionEvent arg0) {
    x2=x2+i;
    y2=y2+j;
    time.stop();
    time.start();
    repaint();
  }

  public void paintComponent(Graphics newG) {
    super.paintComponent(newG);
    Graphics2D g2d = (Graphics2D)newG;
    animateLine(g2d);
  }
}

【问题讨论】:

  • 1) 使用逻辑一致的缩进代码行和块的形式。缩进是为了让代码流更容易理解! 2) 为了尽快获得更好的帮助,请发布MCVE(最小完整可验证示例)或SSCCE(简短、自包含、正确示例)。 3)time.stop();(是如何停止动画)。
  • 可能的建议:将动画线绘制到JPanel 的paintComponent 方法覆盖(您没有显示),并将完成的线绘制到同样在paintComponent 中绘制的BufferedImage。是的,编辑你的代码,使其可读。强迫这里的人们阅读难以阅读的代码并不是一种好的形式。
  • 抱歉,如果每行缩进 4 个空格,则此处不会显示为“代码”。
  • 停止道歉并按照我的建议发布 MCVE。
  • 是的,只要你在该方法中加入一些逻辑,包括 if 条件,它就可以在 actionPerformed 中完成。但我也赞同@AndrewThompson 的建议,请发布您的mcve,以便我们更轻松地学习和运行您的代码。

标签: java swing animation time line


【解决方案1】:

我建议您使用两个组件来绘制线条,即动态和静态。动态组件是处于动画过程中的线条,为此,您应该在 JPanel 的 paintComponent 方法中进行绘图。一旦这条线被完全绘制出来,那么它应该被更永久地绘制到一个 BufferedImage 上,它表示图像的静态部分,它也在 paintComponent 中绘制。 paintComponent 可能看起来像这样:

@Override
protected void paintComponent(Graphics g) {

    super. paintComponent(g);

    // here convert g to Graphics2D and set rendering hints
    // to smooth the line via anti-aliasing

    if (bufferedImg != null) {
        g.drawImage(bufferedImg, 0, 0, null);
    }
    // a boolean check
    if (drawingLine) {
        g.drawLine(x1,y1,x2,y2);
    }
}

然后在你的 Timer 的 actionListener 中,你需要 if 条件:

  • 可以识别当前线何时完成绘制,如果没有,则延长此线。
  • 如果是,则将当前行绘制到 BufferedImage
  • 然后开始新的一行,如果程序逻辑要求这应该发生。

例如

@Override
public void actionPerformed(ActionEvent e) {

    if (lineJustNowCompleted) {
        drawLineToBufferedImage();
    } else if (stillDrawingLine) {
        incrementLineEndPoints();
    } 
    repaint();

}

当然,细节是魔鬼,如果您仍然需要帮助,您需要提供这些细节和更多代码,最好是 MCVE。

【讨论】:

  • 我明白你在这里得到了什么。我发布了完整的代码,但每次我修改 x1 和 y1 的值以使新行从上一行结束的位置开始时,动画不会运行。
  • @caine1337:您在 actionPerformed 中没有逻辑代码来测试该行何时结束以及新行何时开始,而这正是您所需要的。目前只有您知道这些触发器应该是什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-19
  • 2011-11-30
  • 2012-07-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多