如何为圆圈设置动画

时间:2014-03-08 19:07:52

标签: java swing animation timer paintcomponent

我正在学习Java中的GUI。我正在制作这个非常简单的GUI,它每5毫秒逐字地缩放圆形尺寸,然后一旦宽度和高度达到一定数量,它就会缩小并继续执行此过程。我设法让圆圈出现在屏幕上,但由于一些奇怪的原因,它没有缩放。

public class circle extends JPanel implements ActionListener {



    Timer tm = new Timer(5, this);

    int XDiameter = 20;
    int YDiameter = 20;

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
g.setColor(Color.GREEN);
        g.fillOval(40, 40, XDiameter, YDiameter);

        tm.start();
    }



    @Override
    public void actionPerformed(ActionEvent e) {

        SuperSizeCircle();
        repaint();

    }

    public void SuperSizeCircle(){
        while(true){
            XDiameter = XDiameter + 2;
            YDiameter = YDiameter + 2;
            if(XDiameter > 200 && YDiameter > 200){
                XDiameter --;
                YDiameter --;
            }else if(XDiameter < 20 && YDiameter < 20){
            XDiameter ++;
            YDiameter ++;
        }
        }
    }

}

主要课程:

public class main {



public static void main(String[] args) {
    // TODO Auto-generated method stub
    JFrame frame = new JFrame("Circle enlarger");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(400,400);
    frame.setVisible(true);

    circle co = new circle();
    frame.add(co);

}

}

2 个答案:

答案 0 :(得分:2)

  1. while(true)动画中,Swing永远不会好。扔出窗外,永远告别它。从你的方法中取出它。你不需要它。计时器负责“循环”

  2. 请勿在{{1​​}}方法中启动Timer。在构造函数中执行。

  3. 您应该通过将代码包装在paintComponent中,在事件调度线程上运行Swing应用程序。有关详细信息,请参阅Initial Threads

  4. 您应该在添加所有组件后将框架设置为

  5. 如果你看一下逻辑,你SwingUtilities.invokeLater..中的if个陈述会互相混淆。这就是你需要继续添加的原因。这对我来说不合适。相反,我们使用一个标志(布尔值)来确定它是应该增长还是缩小

    SuperSizeCircle()
  6. enter image description here

    boolean grow = true;
    
    public void SuperSizeCircle() {
    
        if (XDiameter >= 200) {
            grow = false;
        }
        if (XDiameter <= 20) {
            grow = true;
        }
    
        if (grow) {
            XDiameter += 2;
            YDiameter += 2;
        } else {
            XDiameter -= 2;
            YDiameter -= 2;
        }
    }
    

答案 1 :(得分:1)

这是一个基于JavaFX的解决方案,仅用于变体。

small big

import javafx.animation.ScaleTransition;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;

public class CircleScaler extends Application {

    private static final double MIN_RADIUS = 10;
    private static final double MAX_RADIUS = 100;
    private static final double PANE_SIZE  = 2 * (MIN_RADIUS + MAX_RADIUS);
    private static final double SCALE_FACTOR = MAX_RADIUS / MIN_RADIUS;
    private static final Duration SCALE_DURATION = Duration.seconds(3);

    @Override
    public void start(Stage stage) {
        final Circle circle = new Circle(MIN_RADIUS, Color.CRIMSON);

        final StackPane root = new StackPane(circle);
        root.setPrefSize(PANE_SIZE, PANE_SIZE);

        stage.setScene(new Scene(root, Color.PALETURQUOISE));
        stage.show();

        animateCircle(circle);
    }

    private void animateCircle(Circle circle) {
        ScaleTransition scaler = new ScaleTransition(
                SCALE_DURATION,
                circle
        );
        scaler.setFromX(1);
        scaler.setToX(SCALE_FACTOR);
        scaler.setFromY(1);
        scaler.setToY(SCALE_FACTOR);

        scaler.setAutoReverse(true);
        scaler.setCycleCount(ScaleTransition.INDEFINITE);
        scaler.play();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

对于JavaFX中更复杂的动画圈子,请参阅james-d's animation of 300 balls