JavaFX为什么AnimationTimer没有getStatus()或类似的方法?

时间:2016-12-18 06:16:05

标签: javafx

似乎很奇怪,AnimationTimer没有一种方法可以知道它是否正在运行......而且我正面临这个问题,因为有时它会启动,有时不会。

解决方案是在volatile variable方法中创建handle(),并且每次在句柄内运行以使其成立并且每次进入stop()时)方法都将其设为false 。所以我必须@Override两种方法。

问题:

为什么AnimationTimer没有确定它是否正在运行的方法?

这是一个糟糕的设计,它因某种原因而丢失了吗?

相关问题:

Is AnimationTimer running in its own thread?

How can I know if an AnimationTimer is running?

2 个答案:

答案 0 :(得分:1)

确实非常奇怪,这种方法很缺失,但除了你和我之外,似乎没有人关心。我已经报道了这个问题 超过4年前,从那时起没有发生任何事情,虽然修复似乎是微不足道的。 JDK-8092345

答案 1 :(得分:0)

从现在起,它有方法isRunning(),直到来自Oracle的兄弟添加它。

通过查看此处虽然它不存在于Java 9 http://download.java.net/java/jdk9/jfxdocs/javafx/animation/AnimationTimer.html中。

AnimationTimer代码:

    /*

 * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.

 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.

 *

 * This code is free software; you can redistribute it and/or modify it

 * under the terms of the GNU General Public License version 2 only, as

 * published by the Free Software Foundation.  Oracle designates this

 * particular file as subject to the "Classpath" exception as provided

 * by Oracle in the LICENSE file that accompanied this code.

 *

 * This code is distributed in the hope that it will be useful, but WITHOUT

 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or

 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License

 * version 2 for more details (a copy is included in the LICENSE file that

 * accompanied this code).

 *

 * You should have received a copy of the GNU General Public License version

 * 2 along with this work; if not, write to the Free Software Foundation,

 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.

 *

 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA

 * or visit www.oracle.com if you need additional information or have any

 * questions.

 */


import com.sun.javafx.tk.Toolkit;

import com.sun.scenario.animation.AbstractMasterTimer;

import com.sun.scenario.animation.shared.TimerReceiver;

import java.security.AccessControlContext;

import java.security.AccessController;

import java.security.PrivilegedAction;


/**

 * The class {@code AnimationTimer} allows to create a timer, that is called in

 * each frame while it is active.

 *

 * An extending class has to override the method {@link #handle(long)} which

 * will be called in every frame.

 *

 * The methods {@link AnimationTimer#start()} and {@link #stop()} allow to start

 * and stop the timer.

 *

 *

 * @since JavaFX 2.0

 */

public abstract class AnimationTimer {


    private class AnimationTimerReceiver implements TimerReceiver {

        @Override public void handle(final long now) {

            if (accessCtrlCtx == null) {

                throw new IllegalStateException("Error: AccessControlContext not captured");

            }


            AccessController.doPrivileged((PrivilegedAction<Void>) () -> {

                AnimationTimer.this.handle(now);

                return null;

            }, accessCtrlCtx);

        }

    }


    private final AbstractMasterTimer timer;

    private final AnimationTimerReceiver timerReceiver = new AnimationTimerReceiver();

    private boolean active;


    // Access control context, captured in start()

    private AccessControlContext accessCtrlCtx = null;


    /**

     * Creates a new timer.

     */

    public AnimationTimer() {

        timer = Toolkit.getToolkit().getMasterTimer();

    }


    // For testing only

    AnimationTimer(AbstractMasterTimer timer) {

        this.timer = timer;

    }


    /**

     * This method needs to be overridden by extending classes. It is going to

     * be called in every frame while the {@code AnimationTimer} is active.

     *

     * @param now

     *            The timestamp of the current frame given in nanoseconds. This

     *            value will be the same for all {@code AnimationTimers} called

     *            during one frame.

     */

    public abstract void handle(long now);


    /**

     * Starts the {@code AnimationTimers}. Once it is started, the

     * {@link #handle(long)} method of this {@code AnimationTimers} will be

     * called in every frame.

     *

     * The {@code AnimationTimers} can be stopped by calling {@link #stop()}.

     */

    public void start() {

        if (!active) {

            // Capture the Access Control Context to be used during the animation pulse

            accessCtrlCtx = AccessController.getContext();

            timer.addAnimationTimer(timerReceiver);

            active = true;

        }

    }


    /**

     * Stops the {@code AnimationTimers}. It can be activated again by calling

     * {@link #start()}.

     */

    public void stop() {

        if (active) {

            timer.removeAnimationTimer(timerReceiver);

            active = false;

        }

    }

    /**Determines if the AnimationTimer is Running
     * @return True if it is running
     */
    public boolean isRunning() {
        return active;
    }

}