JavaFX冻结问题 [英] JavaFX freezing issue

查看:179
本文介绍了JavaFX冻结问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在搞乱JavaFX API,由于某种原因,这个应用程序似乎在(看似)随机的时间后冻结。

I was messing around with the JavaFX API, and for some reason this application seems to freeze after a (seemingly) random amount of time.

这是一个应用程序它制作了一个红绿色的渐变图案,并且有一个很酷的动画。运行应用程序时,按Enter键,动画将开始。经过一段时间(看起来像我之前说的那样随机)它会停止更新,但是计时器继续运行,循环也是如此,并且仍然使用正确的参数调用setColor方法,这让我认为PixelWriter被冻结或窗口没有更新。

It is an application that makes a red-green gradient pattern, and has a kinda cool animation to go along with it. When the application is run, press the Enter key, and the animation will start. After some amount of seconds (seemingly random as I said before) it will stop updating, but the timer continues to run, and so does the loop, and the setColor method is still being called with the proper arguments, leading me to think that either the PixelWriter is frozen or the window isn't updating.

我所做的代码如下:

package me.dean;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.PixelWriter;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

import java.util.Timer;
import java.util.TimerTask;
public class DeansApp extends Application {
    CoolAnimation canvas;

    @Override
    public void start(Stage primaryStage) throws Exception {
        canvas = new CoolAnimation();
        canvas.setWidth(255);
        canvas.setHeight(255);
        primaryStage.setScene(new Scene(new Pane(canvas)));
        canvas.getScene().setOnKeyPressed(event -> {
            if(event.getCode().equals(KeyCode.ENTER)) {
                canvas.play ^= true;
            }
        });

        primaryStage.setOnCloseRequest(event -> System.exit(0));
        primaryStage.show();
    }

    private class CoolAnimation extends Canvas {
        boolean play;
        int column = 0;
        boolean coloring = true;

        public CoolAnimation() {
            super();

            new Timer().schedule(new TimerTask() {
                @Override
                public void run() {
                    if(CoolAnimation.this.play) {
                        GraphicsContext g = getGraphicsContext2D();
                        if(g != null) {
                            PixelWriter writer = g.getPixelWriter();
                            if(writer != null) {
                                for (int x = Math.min(255, column),
                                     y = Math.max(0, column - (int) CoolAnimation.this.getWidth());
                                     x >= 0 && y<=255;
                                     x--, y++) {
                                    writer.setColor(x, y, coloring ? Color.rgb(x, y, 0) : Color.WHITE);
                                }
                            }
                        }
                        column++;
                        if(column >= CoolAnimation.this.getWidth() * 2) {
                            coloring ^= true;
                            column = 0;
                        }
                    }
                }
            }, 0L, 10L);
        }
    }
}

非常感谢任何人能帮忙!

Huge thanks to anyone who is able to help!

推荐答案

你想使用 AnimationTimer 时间轴,而不是 java.util.Timer 。 AnimationTimer或Timeline在JavaFX应用程序线程上执行它的代码,而java.util.Timer则不执行。使用java.util.Timer,您将遇到与线程争用条件相关的随机问题。您可以使用 Platform.runLater 与java.util.Timer结合使用,但一般情况下,使用AnimationTimer是处理此问题的首选方法。

You want to use an AnimationTimer or Timeline, not a java.util.Timer. An AnimationTimer or Timeline executes it's code on the JavaFX Application Thread, whereas a java.util.Timer does not. With a java.util.Timer you will encounter random issues related to thread race conditions. You can use Platform.runLater in combination with a java.util.Timer, but, in general, using an AnimationTimer is the preferred way of handling this.

参见相关内容问题:

  • javafx animation looping

这篇关于JavaFX冻结问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆