更新我的图形

时间:2013-09-10 20:51:10

标签: java swing graphics awt java-2d

我刚开始学习Java编程,甚至最近学习图形,我遇到了一些问题。 我想创建一个像矮人堡垒一样的游戏,用彩色文字而不是图像。

这是我到目前为止所做的:

public void paint(Graphics g) {
    super.paint(g);
    g.setColor(Color.red);

    for (int i = 0; i < 50; i++) {
        g.drawString("[Game goes here]", 100, 150);
        g.dispose();
        System.out.println(i);
    }
    g.dispose();
}

public GTest() {
    setSize(Toolkit.getDefaultToolkit().getScreenSize().width / 3, Toolkit
            .getDefaultToolkit().getScreenSize().width / 3 + 50);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setVisible(true);
}

public static void main(String[] args) {
    GTest myWindow = new GTest();
}

我想让它更新计时器上的图形,但我不确定如何做到这一点。

我知道这是一个非常广泛的问题,我很乐意澄清你可能想知道的任何事情。

编辑:

所以我添加了这一点:

String[] letters = new String[10];
float fontsize = Toolkit.getDefaultToolkit().getScreenSize().width / 30;

public void paint(Graphics g) {

    g.setColor(textColor);
    setFont(getFont().deriveFont(fontsize));
    for(int i = 0; i < 10; i++){
        if((int) (Math.random() * 100) > 97){
            letters[i] = "w";
            textColor = new Color(0, 0, 100);

        }else{
            letters[i] = "l";
            textColor = new Color(0, 100, 0);
        }
        g.drawString(letters[i], i * 3, 10);
    }

但现在它根本不显示。我在g.drawString之后添加了一个sysout,它执行了它所以我不确定是什么问题。

2 个答案:

答案 0 :(得分:2)

在Swing中根据计时器执行任何操作时,javax.swing.Timer课程是您最好的朋友。

这是JavaDocs很好地解释了它的用法,所以这是一个例子。

public class GTest extends JFrame implements ActionListener {
    private Color textColor = Color.BLACK;
    private Random random = new Random();

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.setColor(textColor);
        g.drawString("[Game goes here]", 100, 150);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        textColor = new Color(random.nextInt(0x00ffffff));
        repaint();
    }

    public GTest() {
        setSize(Toolkit.getDefaultToolkit().getScreenSize().width / 3,
                Toolkit.getDefaultToolkit().getScreenSize().width / 3 + 50);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        Timer timer = new Timer(500, this);
        timer.setInitialDelay(0);
        timer.start();

        setVisible(true);
    }

    public static void main(String[] args) {
        GTest myWindow = new GTest();
    }
}

这又是你的GTest课程,但这次文字颜色每0.5秒自动更改一次。

请注意两个主要变化:

  1. 构造函数现在设置Timer的新实例,没有初始延迟,周期为500毫秒,其侦听器设置为this。这意味着这个构造的实例将监听该计时器的滴答声。
  2. 为此,我们需要实现ActionListener接口。这迫使我们编写actionPerformed()方法,每次定时器滴答时调用该方法。在此方法中,我们将textcolor更改为随机文本并调用repaint(),然后调用我们的paint()方法并获取文本。

  3. P.S。您每次都不必dispose() Graphicspaint()个对象。它实际上也在JavaDoc中说过(强调我的):

      

    作为update()dispose()的参数提供的图形对象   组件的Graphics方法由系统自动释放   当那些方法返回时。为了提高效率,程序员应该致电   仅在Graphics对象创建完成后才使用{{1}}   直接来自组件或其他{{1}}对象

答案 1 :(得分:2)

首先,如果您没有创建Graphics上下文的副本,则不应该将其处理掉。这实际上可以防止您的申请表的其他部分被绘制;)

其次。我会避免从顶级容器延伸,比如JFrame,除了允许你在窗口的框架/边框装饰下绘制,它们不是双缓冲的。

相反,我会使用类似JPanel的内容,并覆盖其paintComponent方法。这将为您提供自动双缓冲。

因为Swing是单线程框架,所以期望UI的所有更新都在Event Diapatching Thread的上下文中执行。

在尝试执行等待和同步绘制更新等操作时,这会让生活变得有点困难。

幸运的是,Swing提供了javax.swing.Timer,允许您在将来的某个时间安排活动。这也可以设置为重复和定期间隔。

Timer timer = new Timer(40, new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        // perform your required actions here
    }
});

现在,请注意,actionPerformed方法正在使用EDT的上下文执行,这意味着,您在此处执行的任何长时间运行/耗时处理都可能导致UI停止绘制

看看

了解更多详情......