All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javafx.animation.KeyFrame Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2010, 2022, 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.
 */

package javafx.animation;

import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

import javafx.beans.NamedArg;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.util.Duration;

/**
 * Defines target values at a specified point in time for a set of variables
 * that are interpolated along a {@link Timeline}.
 * 

* The developer controls the interpolation of a set of variables for the * interval between successive key frames by providing a target value and an * {@link Interpolator} associated with each variable. The variables are * interpolated such that they will reach their target value at the specified * time. An {@code onFinished} function is invoked on each {@code KeyFrame} if one * is provided. A {@code KeyFrame} can optionally have a {@code name}, which * will result in a cuepoint that is automatically added to the {@code Timeline}. * * @see Timeline * @see KeyValue * @see Interpolator * * @since JavaFX 2.0 */ public final class KeyFrame { private static final EventHandler DEFAULT_ON_FINISHED = null; private static final String DEFAULT_NAME = null; /** * Returns the time offset of this {@code KeyFrame}. * * The returned {@link javafx.util.Duration} defines the time offset within * a single cycle of a {@link Timeline} at which the {@link KeyValue * KeyValues} will be set and at which the {@code onFinished} function * variable will be called. *

* The {@code time} of a {@code KeyFrame} has to be greater than or equal to * {@link javafx.util.Duration#ZERO} and it cannot be * {@link javafx.util.Duration#UNKNOWN}. * * Note: While the unit of {@code time} is a millisecond, the granularity * depends on the underlying operating system and will in general be larger. * For example animations on desktop systems usually run with a maximum of * 60fps which gives a granularity of ~17 ms. * @return the time offset */ public Duration getTime() { return time; } private final Duration time; /** * Returns an immutable {@code Set} of {@link KeyValue} instances. * * A {@code KeyValue} defines a target and the desired value that should be * interpolated at the specified time of this {@code KeyFrame}. * @return an immutable {@code Set} of {@link KeyValue} instances */ public Set getValues() { return values; } private final Set values; /** * Returns the {@code onFinished} event handler of this {@code KeyFrame}. * * The {@code onFinished} event handler is a function that is called when * the elapsed time on a cycle passes the specified time of this * {@code KeyFrame}. The {@code onFinished} function variable will be called * if the elapsed time passes the indicated value, even if it never equaled * the time value exactly. * @return the {@code onFinished} event handler */ public EventHandler getOnFinished() { return onFinished; } private final EventHandler onFinished; /** * Returns the {@code name} of this {@code KeyFrame}. * * If a named {@code KeyFrame} is added to a {@link Timeline}, a cuepoint * with the {@code name} and the {@code time} of the {@code KeyFrame} will * be added automatically. If the {@code KeyFrame} is removed, the cuepoint * will also be removed. * @return the {@code name} */ public String getName() { return name; } private final String name; /** * Constructor of {@code KeyFrame} *

* If a passed in {@code KeyValue} is {@code null} or a duplicate, it will * be ignored. * * @param time * the {@code time} * @param name * the {@code name} * @param onFinished * the {@code onFinished} * @param values * a {@link javafx.collections.ObservableList} of * {@link KeyValue} instances * @throws NullPointerException * if {@code time} is null * @throws IllegalArgumentException * if {@code time} is invalid (see {@link #getTime time}) */ public KeyFrame(@NamedArg("time") Duration time, @NamedArg("name") String name, @NamedArg("onFinished") EventHandler onFinished, @NamedArg("values") Collection values) { if (time == null) { throw new NullPointerException("The time has to be specified"); } if (time.lessThan(Duration.ZERO) || time.equals(Duration.UNKNOWN)) { throw new IllegalArgumentException("The time is invalid."); } this.time = time; this.name = name; if (values != null) { final Set set = new CopyOnWriteArraySet<>(values); set.remove(null); this.values = (set.size() == 0) ? Collections. emptySet() : (set.size() == 1) ? Collections. singleton(set .iterator().next()) : Collections .unmodifiableSet(set); } else { this.values = Collections. emptySet(); } this.onFinished = onFinished; } /** * Constructor of {@code KeyFrame} *

* If a passed in {@code KeyValue} is {@code null} or a duplicate, it will * be ignored. * * @param time * the {@code time} * @param name * the {@code name} * @param onFinished * the {@code onFinished} * @param values * the {@link KeyValue} instances * @throws NullPointerException * if {@code time} is null * @throws IllegalArgumentException * if {@code time} is invalid (see {@link #getTime time}) */ public KeyFrame(@NamedArg("time") Duration time, @NamedArg("name") String name, @NamedArg("onFinished") EventHandler onFinished, @NamedArg("values") KeyValue... values) { if (time == null) { throw new NullPointerException("The time has to be specified"); } if (time.lessThan(Duration.ZERO) || time.equals(Duration.UNKNOWN)) { throw new IllegalArgumentException("The time is invalid."); } this.time = time; this.name = name; if (values != null) { final Set set = new CopyOnWriteArraySet<>(); for (final KeyValue keyValue : values) { if (keyValue != null) { set.add(keyValue); } } this.values = (set.size() == 0) ? Collections. emptySet() : (set.size() == 1) ? Collections. singleton(set .iterator().next()) : Collections .unmodifiableSet(set); } else { this.values = Collections.emptySet(); } this.onFinished = onFinished; } /** * Constructor of {@code KeyFrame} * * @param time * the {@code time} * @param onFinished * the {@code onFinished} * @param values * the {@link KeyValue} instances * @throws NullPointerException * if {@code time} is null * @throws IllegalArgumentException * if {@code time} is invalid (see {@link #getTime time}) */ public KeyFrame(@NamedArg("time") Duration time, @NamedArg("onFinished") EventHandler onFinished, @NamedArg("values") KeyValue... values) { this(time, DEFAULT_NAME, onFinished, values); } /** * Constructor of {@code KeyFrame} * * @param time * the {@code time} * @param name * the {@code name} * @param values * the {@link KeyValue} instances * @throws NullPointerException * if {@code time} is null * @throws IllegalArgumentException * if {@code time} is invalid (see {@link #getTime time}) */ public KeyFrame(@NamedArg("time") Duration time, @NamedArg("name") String name, @NamedArg("values") KeyValue... values) { this(time, name, DEFAULT_ON_FINISHED, values); } /** * Constructor of {@code KeyFrame} * * @param time * the {@code time} * @param values * the {@link KeyValue} instances * @throws NullPointerException * if {@code time} is null * @throws IllegalArgumentException * if {@code time} is invalid (see {@link #getTime time}) */ public KeyFrame(@NamedArg("time") Duration time, @NamedArg("values") KeyValue... values) { this(time, DEFAULT_NAME, DEFAULT_ON_FINISHED, values); } /** * Returns a string representation of this {@code KeyFrame} object. * @return the string representation */ @Override public String toString() { return "KeyFrame [time=" + time + ", values=" + values + ", onFinished=" + onFinished + ", name=" + name + "]"; } /** * Returns a hash code for this {@code KeyFrame} object. * @return the hash code */ @Override public int hashCode() { assert (time != null) && (values != null); final int prime = 31; int result = 1; result = prime * result + time.hashCode(); result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((onFinished == null) ? 0 : onFinished.hashCode()); result = prime * result + values.hashCode(); return result; } /** * Indicates whether some other object is "equal to" this one. * Two {@code KeyFrames} are considered equal, if their {@link #getTime() * time}, {@link #getOnFinished onFinished}, and {@link #getValues() values} * are equal. * @return {@code true} if this is the same as obj, otherwise {@code false} */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj instanceof KeyFrame) { final KeyFrame kf = (KeyFrame) obj; assert (time != null) && (values != null) && (kf.time != null) && (kf.values != null); return time.equals(kf.time) && ((name == null) ? kf.name == null : name.equals(kf.name)) && ((onFinished == null) ? kf.onFinished == null : onFinished.equals(kf.onFinished)) && values.equals(kf.values); } return false; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy