我正在学习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);
}
}
答案 0 :(得分:2)
在while(true)
动画中,Swing
永远不会好。扔出窗外,永远告别它。从你的方法中取出它。你不需要它。计时器负责“循环”
请勿在{{1}}方法中启动Timer
。在构造函数中执行。
您应该通过将代码包装在paintComponent
中,在事件调度线程上运行Swing应用程序。有关详细信息,请参阅Initial Threads。
您应该在添加所有组件后将框架设置为。
如果你看一下逻辑,你SwingUtilities.invokeLater..
中的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;
}
}
答案 1 :(得分:1)
这是一个基于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's animation of 300 balls。