簡體   English   中英

如何為圓圈設置動畫

[英]how to animate a circle

我正在學習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);

}

}

  1. while(true)Swing動畫中永遠不會好。 扔出窗外,永遠告別它。 從你的方法中取出它。 你不需要它。 計時器負責“循環”

  2. 不要在paintComponent方法中啟動Timer 在構造函數中執行。

  3. 您應該通過將代碼包裝在SwingUtilities.invokeLater..來在Event Dispatch Thread上運行Swing應用程序。 有關詳細信息,請參閱初始線程

  4. 您應該添加所有組件后將框架設置為可見。

  5. if在你的語句SuperSizeCircle()相互亂,如果你看一下邏輯。 這就是你需要繼續添加的原因。 這對我來說不合適。 相反,我們使用一個標志(布爾值)來確定它是應該增長還是縮小

     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; } } 

在此輸入圖像描述

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class CirclePanel extends JPanel implements ActionListener {

    Timer tm = new Timer(15, this);

    boolean grow = true;

    int XDiameter = 20;
    int YDiameter = 20;

    public CirclePanel() {
        tm.start();
    }

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

    @Override
    public void actionPerformed(ActionEvent e) {

        SuperSizeCircle();
        repaint();

    }

    public void SuperSizeCircle() {

        if (XDiameter >= 200) {
            grow = false;
        }
        if (XDiameter <= 20) {
            grow = true;
        }

        if (grow) {
            XDiameter += 3;
            YDiameter += 3;
        } else {
            XDiameter -= 3;
            YDiameter -= 3;
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame("Circle enlarger");
                CirclePanel co = new CirclePanel();
                frame.add(co);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setSize(300, 300);
                frame.setVisible(true);
            }
        });
    }
}

這是一個基於JavaFX的解決方案,僅用於變體。

小大

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的300個球的動畫

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM