java canvas抽绳

时间:2011-08-09 23:39:23

标签: java user-interface canvas

我希望在随机位置绘制一个字符串,然后跳转到一个新位置,但留下自己的印记。

在java中似乎没有“stamp”命令。

我该怎么做?

到目前为止,我只有一个随机字符可以跳转,但不会留下自己的副本。

import java.awt.Canvas;
import java.awt.Graphics;
import java.util.Random;

import javax.swing.JFrame;

@SuppressWarnings("serial")
public class test extends Canvas {

private static Random random = new Random();

public void paint(Graphics g) {
    g.drawString("X", random.nextInt(10) * 10, random.nextInt(10) * 10);

    try {
        Thread.sleep(250);
    } catch (Exception e ) {}

    repaint();
}

public static void main(String[] argS) {
    test canvas = new test();
    JFrame frame = new JFrame();
    frame.add(canvas);
    frame.setSize(300, 300);
    frame.setVisible(true);
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

3 个答案:

答案 0 :(得分:4)

建议:

  • 不要将Swing与AWT组件混合 - 因此使用JPanel代替Canvas对象。
  • 覆盖JPanel的paintComponent方法。
  • 将super.paintComponent方法作为paintComponent的第一行。
  • 使用Swing Timer进行动画,不要将Thread.sleep放在paint或paintComponent方法中。事实上,除非你知道如何在Swing中处理并发,否则你应该避免在Swing GUI中的任何地方使用Thread.sleep。
  • 永远不要在paint或paintComponent方法中调用repaint()。你很幸运,paint manager足够智能,不允许该调用导致递归引起的stackoverflow错误。

答案 1 :(得分:1)

当您使用repaint时,AWT系统将调用画布'update()方法,该方法将清除图形(通过在背景颜色中绘制矩形),然后调用paint() 。 (这是针对AWT的重量级组件,如Canvas - 对于Swing,它有点不同。)

因此,通过覆盖update来清除组件,将给出一个简单的解决方法:

public void update(Graphics g) {
    this.paint(g);
}

请注意,当系统决定您的组件必须无效时,旧的绘制字符串仍可能消失,例如在另一个窗口覆盖它之后。

与此无关:

你永远不应该睡在绘画方法中(其他可能用于调试)。该绘制将在事件派发线程中完成,只要paint方法未完成,就不会调度任何事件。不要这样做。

相反,让一个单独的线程(甚至是主线程)做一个睡眠并调用repaint的循环。

另外,正如Hovercraft所说,不要将AWT与Swing混合使用。如果您想使用Frame,请使用AWT Canvas代替Swing的JFrame。

答案 2 :(得分:1)

只需保留所有以前的位置并将其打印出来,也许是另外一个 颜色。您也不会说您是希望永久打印字符还是仅保留几帧可见字符。如果你希望它们在一段时间后消失,你可以将你的随机位置放在一个队列中,并在绘制新帧时删除队列的尾部元素(摆脱旧的位置,使它们不被绘制)。

(Hovercraft和Paulo的建议也很有用。)