[英]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);
}
}
while(true)
在Swing
動畫中永遠不會好。 扔出窗外,永遠告別它。 從你的方法中取出它。 你不需要它。 計時器負責“循環”
不要在paintComponent
方法中啟動Timer
。 在構造函數中執行。
您應該通過將代碼包裝在SwingUtilities.invokeLater..
來在Event Dispatch Thread上運行Swing應用程序。 有關詳細信息,請參閱初始線程 。
您應該在添加所有組件后將框架設置為可見。
您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.