【问题标题】:Java Swing basic animation issueJava Swing基本动画问题
【发布时间】:2015-11-20 20:06:24
【问题描述】:

我刚开始学习 GUI 和 Swing,并决定编写一个我在教科书中找到的程序来显示一个彩色矩形,让它在屏幕上看起来像缩小了一样。

以下是我编写的代码,我的问题是矩形显示在屏幕上,但不是每 50 毫秒重新绘制为更小的尺寸。谁能指出我在哪里出错了?

非常感谢

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

public class Animate {

int x = 1;
int y = 1;

public static void main(String[] args){

    Animate gui = new Animate();
    gui.start();

}

public void start(){

    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    Rectangles rectangles = new Rectangles();

    frame.getContentPane().add(rectangles);
    frame.setSize(500,270);
    frame.setVisible(true);

    for(int i = 0; i < 100; i++,y++,x++){

        x++;
        rectangles.repaint();

        try {
            Thread.sleep(50);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

}





class Rectangles extends JPanel {

public void paintComponent(Graphics g){
    g.setColor(Color.blue);
    g.fillRect(x, y, 500-x*2, 250-y*2);
}

}
}

【问题讨论】:

  • 您是否进行了任何基本调试?您是否在您的绘制方法中添加了一条语句以查看它是否被调用?你显示 x/y 的值了吗?

标签: java swing user-interface paintcomponent repaint


【解决方案1】:

矩形显示在屏幕上,但不会每 50 毫秒重新绘制为更小的尺寸

进行自定义绘画时,基本代码应该是:

protected void paintComponent(Graphics g)
{
    super.paintComponent(g); // to clear the background

    //  add custom painting code
}

如果您不清除背景,则旧画仍然存在。所以画更小的东西不会有什么不同。

为了更好的代码结构,x/y 变量应该在Rectangles 类中定义。然后你应该创建一个类似decreaseSize() 的方法,它也在你的Rectangles 类中定义。此代码将更新 x/y 值,然后对其自身调用重绘。所以你的动画代码只会调用decreaseSize() 方法。

【讨论】:

  • 现在说得通了,谢谢。我将尝试创建您建议的方法
【解决方案2】:
  1. 您应该重新绘制整个 JFrame(或您的图形所在的 JPanel)。
  2. 您不必拨打x++ 两次,而是拨打x+=2

将您的代码更改为此(有效,我还修复了缩进):

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

public class Animate {

    int x = 1;
    int y = 1;

    public static void main(String[] args) {

        Animate gui = new Animate();
        gui.start();

    }

    public void start() {

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Rectangles rectangles = new Rectangles();

        frame.getContentPane().add(rectangles);
        frame.setSize(500, 270);
        frame.setVisible(true);

        for (int i = 0; i < 100; i++, y++, x += 2) {
            frame.repaint();

            try {
                Thread.sleep(50);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }

    }

    class Rectangles extends JPanel {

        public void paintComponent(Graphics g) {
            g.setColor(Color.blue);
            g.fillRect(x, y, 500 - x * 2, 250 - y * 2);
        }

    }
}

【讨论】:

  • 1) 没有理由重新绘制整个框架。如果只有面板发生变化,那么只需重新绘制面板。 2) 好建议,但发布的代码未在 EDT 上执行。从 main 方法执行的代码在普通线程上调用,除非代码包装在 SwingUtilities.invokeLater(...) 中。
  • @camickr 他没有创建 JPanel,而是将所有内容添加到 JFrame 的内容窗格中。 (但感谢您指出我的陈述不正确(与第 2 点相同))。
猜你喜欢
  • 2014-04-20
  • 1970-01-01
  • 1970-01-01
  • 2013-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-06
  • 1970-01-01
相关资源
最近更新 更多