/* * Copyright (c) 2011, 2016, 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.scene.transform; import java.util.Iterator; import com.sun.javafx.geometry.BoundsUtils; import javafx.event.EventDispatchChain; import javafx.scene.Node; import com.sun.javafx.util.WeakReferenceQueue; import com.sun.javafx.binding.ExpressionHelper; import com.sun.javafx.event.EventHandlerManager; import com.sun.javafx.geom.transform.Affine3D; import com.sun.javafx.geom.transform.BaseTransform; import com.sun.javafx.scene.transform.TransformHelper; import com.sun.javafx.scene.transform.TransformUtils; import java.lang.ref.SoftReference; import javafx.beans.InvalidationListener; import javafx.beans.property.ObjectProperty; import javafx.beans.property.ReadOnlyBooleanProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ChangeListener; import javafx.event.Event; import javafx.event.EventHandler; import javafx.event.EventTarget; import javafx.event.EventType; import javafx.geometry.Bounds; import javafx.geometry.Point2D; import javafx.geometry.Point3D; // PENDING_DOC_REVIEW of this whole class /** * This class is a base class for different affine transformations. * It provides factory methods for the simple transformations - rotating, * scaling, shearing, and translation. It allows to get the transformation * matrix elements for any transform. * *
Example:
* *
* Rectangle rect = new Rectangle(50,50, Color.RED);
* rect.getTransforms().add(new Rotate(45,0,0)); //rotate by 45 degrees
*
* @since JavaFX 2.0
*/
public abstract class Transform implements Cloneable, EventTarget {
static {
// This is used by classes in different packages to get access to
// private and package private methods.
TransformHelper.setTransformAccessor(new TransformHelper.TransformAccessor() {
@Override
public void add(Transform transform, Node node) {
transform.add(node);
}
@Override
public void remove(Transform transform, Node node) {
transform.remove(node);
}
@Override
public void apply(Transform transform, Affine3D affine3D) {
transform.apply(affine3D);
}
@Override
public BaseTransform derive(Transform transform, BaseTransform baseTransform) {
return transform.derive(baseTransform);
}
@Override
public Transform createImmutableTransform() {
return Transform.createImmutableTransform();
}
@Override
public Transform createImmutableTransform(
double mxx, double mxy, double mxz, double tx,
double myx, double myy, double myz, double ty,
double mzx, double mzy, double mzz, double tz) {
return Transform.createImmutableTransform(mxx, mxy, mxz, tx,
myx, myy, myz, ty, mzx, mzy, mzz, tz);
}
@Override
public Transform createImmutableTransform(Transform transform,
double mxx, double mxy, double mxz, double tx,
double myx, double myy, double myz, double ty,
double mzx, double mzy, double mzz, double tz) {
return Transform.createImmutableTransform(transform,
mxx, mxy, mxz, tx, myx, myy, myz, ty, mzx, mzy, mzz, tz);
}
@Override
public Transform createImmutableTransform(Transform transform,
Transform left, Transform right) {
return Transform.createImmutableTransform(transform, left, right);
}
});
}
/* *************************************************************************
* *
* Factories *
* *
**************************************************************************/
/**
* Returns a new {@code Affine} object from 12 number
* values representing the 6 specifiable entries of the 3x4
* Affine transformation matrix.
*
* @param mxx the X coordinate scaling element of the 3x4 matrix
* @param myx the Y coordinate shearing element of the 3x4 matrix
* @param mxy the X coordinate shearing element of the 3x4 matrix
* @param myy the Y coordinate scaling element of the 3x4 matrix
* @param tx the X coordinate translation element of the 3x4 matrix
* @param ty the Y coordinate translation element of the 3x4 matrix
* @return a new {@code Affine} object derived from specified parameters
*/
public static Affine affine(
double mxx, double myx, double mxy, double myy, double tx, double ty) {
final Affine affine = new Affine();
affine.setMxx(mxx);
affine.setMxy(mxy);
affine.setTx(tx);
affine.setMyx(myx);
affine.setMyy(myy);
affine.setTy(ty);
return affine;
}
/**
* Returns a new {@code Affine} object from 12 number
* values representing the 12 specifiable entries of the 3x4
* Affine transformation matrix.
*
* @param mxx the X coordinate scaling element of the 3x4 matrix
* @param mxy the XY element of the 3x4 matrix
* @param mxz the XZ element of the 3x4 matrix
* @param tx the X coordinate translation element of the 3x4 matrix
* @param myx the YX element of the 3x4 matrix
* @param myy the Y coordinate scaling element of the 3x4 matrix
* @param myz the YZ element of the 3x4 matrix
* @param ty the Y coordinate translation element of the 3x4 matrix
* @param mzx the ZX element of the 3x4 matrix
* @param mzy the ZY element of the 3x4 matrix
* @param mzz the Z coordinate scaling element of the 3x4 matrix
* @param tz the Z coordinate translation element of the 3x4 matrix
* @return a new {@code Affine} object derived from specified parameters
*/
public static Affine affine(
double mxx, double mxy, double mxz, double tx,
double myx, double myy, double myz, double ty,
double mzx, double mzy, double mzz, double tz) {
final Affine affine = new Affine();
affine.setMxx(mxx);
affine.setMxy(mxy);
affine.setMxz(mxz);
affine.setTx(tx);
affine.setMyx(myx);
affine.setMyy(myy);
affine.setMyz(myz);
affine.setTy(ty);
affine.setMzx(mzx);
affine.setMzy(mzy);
affine.setMzz(mzz);
affine.setTz(tz);
return affine;
}
/**
* Returns a {@code Translate} object representing a translation transformation.
* * This is equivalent to: *
* new Translate(x, y); **/ public static Translate translate(double x, double y) { final Translate translate = new Translate(); translate.setX(x); translate.setY(y); return translate; } /** * Returns a {@code Rotate} object that rotates coordinates around a pivot * point. *
* This is equivalent to: *
* new Rotate(angle, pivotX, pivotY); **/ public static Rotate rotate(double angle, double pivotX, double pivotY) { final Rotate rotate = new Rotate(); rotate.setAngle(angle); rotate.setPivotX(pivotX); rotate.setPivotY(pivotY); return rotate; } /** * Returns a {@code Scale} object representing a scaling transformation. *
* This is equivalent to: *
* new Scale(x, y); **/ public static Scale scale(double x, double y) { final Scale scale = new Scale(); scale.setX(x); scale.setY(y); return scale; } /** * Returns a {@code Scale} object representing a scaling transformation. * The returned scale operation will be about the given pivot point. *
* This is equivalent to: *
* new Scale(x, y, pivotX, pivotY); **/ public static Scale scale(double x, double y, double pivotX, double pivotY) { final Scale scale = new Scale(); scale.setX(x); scale.setY(y); scale.setPivotX(pivotX); scale.setPivotY(pivotY); return scale; } /** * Returns a {@code Shear} object representing a shearing transformation. *
* This is equivalent to: *
* new Shear(x, y); **/ public static Shear shear(double x, double y) { final Shear shear = new Shear(); shear.setX(x); shear.setY(y); return shear; } /** * Returns a {@code Shear} object representing a shearing transformation. *
* This is equivalent to: *
* new Shear(x, y, pivotX, pivotY); **/ public static Shear shear(double x, double y, double pivotX, double pivotY) { final Shear shear = new Shear(); shear.setX(x); shear.setY(y); shear.setPivotX(pivotX); shear.setPivotY(pivotY); return shear; } /** * For transforms with expensive inversion we cache the inverted matrix * once it is needed and computed for some operation. */ private SoftReference
[x0, y0, x1, y1, ..., xn, yn]
.
* This method can be used only for 2D transforms.
* @param srcPts the array containing the source point coordinates.
* Each point is stored as a pair of x, y coordinates.
* @param srcOff the offset to the first point to be transformed
* in the source array
* @param dstPts the array into which the transformed point coordinates
* are returned. Each point is stored as a pair of x, y
* coordinates.
* @param dstOff the offset to the location of the first
* transformed point that is stored in the destination array
* @param numPts the number of points to be transformed
* @throws IllegalStateException if this is a 3D transform
* @throws NullPointerException if {@code srcPts} or (@code dstPts} is null
* @since JavaFX 8.0
*/
public void transform2DPoints(double[] srcPts, int srcOff,
double[] dstPts, int dstOff,
int numPts) {
if (srcPts == null || dstPts == null) {
throw new NullPointerException();
}
if (!isType2D()) {
throw new IllegalStateException("Cannot transform 2D points "
+ "with a 3D transform");
}
// deal with overlapping arrays
srcOff = getFixedSrcOffset(srcPts, srcOff, dstPts, dstOff, numPts, 2);
// do the transformations
transform2DPointsImpl(srcPts, srcOff, dstPts, dstOff, numPts);
}
/**
* Transforms an array of floating point coordinates by this transform.
* The three coordinate array sections can be exactly the same or
* can be overlapping sections of the same array without affecting the
* validity of the results.
* This method ensures that no source coordinates are overwritten by a
* previous operation before they can be transformed.
* The coordinates are stored in the arrays starting at the specified
* offset in the order [x0, y0, z0, x1, y1, z1, ..., xn, yn, zn]
.
* @param srcPts the array containing the source point coordinates.
* Each point is stored as a tiplet of x, y, z coordinates.
* @param srcOff the offset to the first point to be transformed
* in the source array
* @param dstPts the array into which the transformed point coordinates
* are returned. Each point is stored as a triplet of x, y, z
* coordinates.
* @param dstOff the offset to the location of the first
* transformed point that is stored in the destination array
* @param numPts the number of points to be transformed
* @throws NullPointerException if {@code srcPts} or (@code dstPts} is null
* @since JavaFX 8.0
*/
public void transform3DPoints(double[] srcPts, int srcOff,
double[] dstPts, int dstOff,
int numPts) {
if (srcPts == null || dstPts == null) {
throw new NullPointerException();
}
// deal with overlapping arrays
srcOff = getFixedSrcOffset(srcPts, srcOff, dstPts, dstOff, numPts, 3);
// do the transformations
transform3DPointsImpl(srcPts, srcOff, dstPts, dstOff, numPts);
}
/**
* Transforms the relative magnitude vector by this transform.
* The vector is transformed without applying the translation components
* of the affine transformation matrix.
* This method can be used only for a 2D transform.
* @param x vector magnitude in the direction of the X axis
* @param y vector magnitude in the direction of the Y axis
* @return the transformed relative magnitude vector represented
* by a {@code Point2D} instance
* @throws IllegalStateException if this is a 3D transform
* @since JavaFX 8.0
*/
public Point2D deltaTransform(double x, double y) {
ensureCanTransform2DPoint();
return new Point2D(
getMxx() * x + getMxy() * y,
getMyx() * x + getMyy() * y);
}
/**
* Transforms the relative magnitude vector represented by the specified
* {@code Point2D} instance by this transform.
* The vector is transformed without applying the translation components
* of the affine transformation matrix.
* This method can be used only for a 2D transform.
* @param point the relative magnitude vector
* @return the transformed relative magnitude vector represented
* by a {@code Point2D} instance
* @throws IllegalStateException if this is a 3D transform
* @throws NullPointerException if the specified {@code point} is null
* @since JavaFX 8.0
*/
public Point2D deltaTransform(Point2D point) {
return deltaTransform(point.getX(), point.getY());
}
/**
* Transforms the relative magnitude vector by this transform.
* The vector is transformed without applying the translation components
* of the affine transformation matrix.
* @param x vector magnitude in the direction of the X axis
* @param y vector magnitude in the direction of the Y axis
* @return the transformed relative magnitude vector represented
* by a {@code Point3D} instance
* @since JavaFX 8.0
*/
public Point3D deltaTransform(double x, double y, double z) {
return new Point3D(
getMxx() * x + getMxy() * y + getMxz() * z,
getMyx() * x + getMyy() * y + getMyz() * z,
getMzx() * x + getMzy() * y + getMzz() * z);
}
/**
* Transforms the relative magnitude vector represented by the specified
* {@code Point3D} instance by this transform.
* The vector is transformed without applying the translation components
* of the affine transformation matrix.
* @param point the relative magnitude vector
* @return the transformed relative magnitude vector represented
* by a {@code Point3D} instance
* @throws NullPointerException if the specified {@code point} is null
* @since JavaFX 8.0
*/
public Point3D deltaTransform(Point3D point) {
return deltaTransform(point.getX(), point.getY(), point.getZ());
}
/**
* Transforms the specified point by the inverse of this transform.
* This method can be used only for 2D transforms.
* @param x the X coordinate of the point
* @param y the Y coordinate of the point
* @return the inversely transformed point
* @throws IllegalStateException if this is a 3D transform
* @throws NonInvertibleTransformException if this transform
* cannot be inverted
* @since JavaFX 8.0
*/
public Point2D inverseTransform(double x, double y)
throws NonInvertibleTransformException {
ensureCanTransform2DPoint();
return getInverseCache().transform(x, y);
}
/**
* Transforms the specified point by the inverse of this transform.
* This method can be used only for 2D transforms.
* @param point the point to be transformed
* @return the inversely transformed point
* @throws IllegalStateException if this is a 3D transform
* @throws NonInvertibleTransformException if this transform
* cannot be inverted
* @throws NullPointerException if the specified {@code point} is null
* @since JavaFX 8.0
*/
public Point2D inverseTransform(Point2D point)
throws NonInvertibleTransformException {
return inverseTransform(point.getX(), point.getY());
}
/**
* Transforms the specified point by the inverse of this transform.
* @param x the X coordinate of the point
* @param y the Y coordinate of the point
* @param z the Z coordinate of the point
* @return the inversely transformed point
* @throws NonInvertibleTransformException if this transform
* cannot be inverted
* @since JavaFX 8.0
*/
public Point3D inverseTransform(double x, double y, double z)
throws NonInvertibleTransformException {
return getInverseCache().transform(x, y, z);
}
/**
* Transforms the specified point by the inverse of this transform.
* @param point the point to be transformed
* @return the inversely transformed point
* @throws NonInvertibleTransformException if this transform
* cannot be inverted
* @throws NullPointerException if the specified {@code point} is null
* @since JavaFX 8.0
*/
public Point3D inverseTransform(Point3D point)
throws NonInvertibleTransformException {
return inverseTransform(point.getX(), point.getY(), point.getZ());
}
/**
* Transforms the specified bounds by the inverse of this transform.
* @param bounds the bounds to be transformed
* @return the inversely transformed bounds
* @throws NonInvertibleTransformException if this transform
* cannot be inverted
* @throws NullPointerException if the specified {@code bounds} is null
* @since JavaFX 8.0
*/
public Bounds inverseTransform(Bounds bounds)
throws NonInvertibleTransformException {
if (isType2D() && (bounds.getMinZ() == 0) && (bounds.getMaxZ() == 0)) {
Point2D p1 = inverseTransform(bounds.getMinX(), bounds.getMinY());
Point2D p2 = inverseTransform(bounds.getMaxX(), bounds.getMinY());
Point2D p3 = inverseTransform(bounds.getMaxX(), bounds.getMaxY());
Point2D p4 = inverseTransform(bounds.getMinX(), bounds.getMaxY());
return BoundsUtils.createBoundingBox(p1, p2, p3, p4);
}
Point3D p1 = inverseTransform(bounds.getMinX(), bounds.getMinY(), bounds.getMinZ());
Point3D p2 = inverseTransform(bounds.getMinX(), bounds.getMinY(), bounds.getMaxZ());
Point3D p3 = inverseTransform(bounds.getMinX(), bounds.getMaxY(), bounds.getMinZ());
Point3D p4 = inverseTransform(bounds.getMinX(), bounds.getMaxY(), bounds.getMaxZ());
Point3D p5 = inverseTransform(bounds.getMaxX(), bounds.getMaxY(), bounds.getMinZ());
Point3D p6 = inverseTransform(bounds.getMaxX(), bounds.getMaxY(), bounds.getMaxZ());
Point3D p7 = inverseTransform(bounds.getMaxX(), bounds.getMinY(), bounds.getMinZ());
Point3D p8 = inverseTransform(bounds.getMaxX(), bounds.getMinY(), bounds.getMaxZ());
return BoundsUtils.createBoundingBox(p1, p2, p3, p4, p5, p6, p7, p8);
}
/**
* Core of the inverseTransform2DPoints method.
* All the checks has been performed and the care of the overlaps has been
* taken by the enclosing method, this method only transforms the points
* and fills them to the array. Used by the subclasses to perform
* the transform efficiently.
*/
void inverseTransform2DPointsImpl(double[] srcPts, int srcOff,
double[] dstPts, int dstOff, int numPts)
throws NonInvertibleTransformException {
getInverseCache().transform2DPointsImpl(srcPts, srcOff,
dstPts, dstOff, numPts);
}
/**
* Core of the inverseTransform3DPoints method.
* All the checks has been performed and the care of the overlaps has been
* taken by the enclosing method, this method only transforms the points
* and fills them to the array. Used by the subclasses to perform
* the transform efficiently.
*/
void inverseTransform3DPointsImpl(double[] srcPts, int srcOff,
double[] dstPts, int dstOff, int numPts)
throws NonInvertibleTransformException {
getInverseCache().transform3DPointsImpl(srcPts, srcOff,
dstPts, dstOff, numPts);
}
/**
* Transforms an array of coordinates by the inverse of this transform.
* The two coordinate array sections can be exactly the same or
* can be overlapping sections of the same array without affecting the
* validity of the results.
* This method ensures that no source coordinates are overwritten by a
* previous operation before they can be transformed.
* The coordinates are stored in the arrays starting at the specified
* offset in the order [x0, y0, x1, y1, ..., xn, yn]
.
* This method can be used only for 2D transforms.
* @param srcPts the array containing the source point coordinates.
* Each point is stored as a pair of x, y coordinates.
* @param srcOff the offset to the first point to be transformed
* in the source array
* @param dstPts the array into which the transformed point coordinates
* are returned. Each point is stored as a pair of x, y
* coordinates.
* @param dstOff the offset to the location of the first
* transformed point that is stored in the destination array
* @param numPts the number of points to be transformed
* @throws IllegalStateException if this is a 3D transform
* @throws NonInvertibleTransformException if this transform
* cannot be inverted
* @throws NullPointerException if {@code srcPts} or (@code dstPts} is null
* @since JavaFX 8.0
*/
public void inverseTransform2DPoints(double[] srcPts, int srcOff,
double[] dstPts, int dstOff,
int numPts) throws NonInvertibleTransformException{
if (srcPts == null || dstPts == null) {
throw new NullPointerException();
}
if (!isType2D()) {
throw new IllegalStateException("Cannot transform 2D points "
+ "with a 3D transform");
}
// deal with overlapping arrays
srcOff = getFixedSrcOffset(srcPts, srcOff, dstPts, dstOff, numPts, 2);
// do the transformations
inverseTransform2DPointsImpl(srcPts, srcOff, dstPts, dstOff, numPts);
}
/**
* Transforms an array of floating point coordinates by the inverse
* of this transform.
* The three coordinate array sections can be exactly the same or
* can be overlapping sections of the same array without affecting the
* validity of the results.
* This method ensures that no source coordinates are overwritten by a
* previous operation before they can be transformed.
* The coordinates are stored in the arrays starting at the specified
* offset in the order [x0, y0, z0, x1, y1, z1, ..., xn, yn, zn]
.
* @param srcPts the array containing the source point coordinates.
* Each point is stored as a triplet of x, y, z coordinates.
* @param srcOff the offset to the first point to be transformed
* in the source array
* @param dstPts the array into which the transformed point coordinates
* are returned. Each point is stored as a triplet of x, y, z
* coordinates.
* @param dstOff the offset to the location of the first
* transformed point that is stored in the destination array
* @param numPts the number of points to be transformed
* @throws NonInvertibleTransformException if this transform
* cannot be inverted
* @throws NullPointerException if {@code srcPts} or (@code dstPts} is null
* @since JavaFX 8.0
*/
public void inverseTransform3DPoints(double[] srcPts, int srcOff,
double[] dstPts, int dstOff,
int numPts) throws NonInvertibleTransformException {
if (srcPts == null || dstPts == null) {
throw new NullPointerException();
}
// deal with overlapping arrays
srcOff = getFixedSrcOffset(srcPts, srcOff, dstPts, dstOff, numPts, 3);
// do the transformations
inverseTransform3DPointsImpl(srcPts, srcOff, dstPts, dstOff, numPts);
}
/**
* Transforms the relative magnitude vector by the inverse of this transform.
* The vector is transformed without applying the translation components
* of the affine transformation matrix.
* This method can be used only for a 2D transform.
* @param x vector magnitude in the direction of the X axis
* @param y vector magnitude in the direction of the Y axis
* @return the inversely transformed relative magnitude vector represented
* by a {@code Point2D} instance
* @throws IllegalStateException if this is a 3D transform
* @throws NonInvertibleTransformException if this transform
* cannot be inverted
* @since JavaFX 8.0
*/
public Point2D inverseDeltaTransform(double x, double y)
throws NonInvertibleTransformException {
ensureCanTransform2DPoint();
return getInverseCache().deltaTransform(x, y);
}
/**
* Transforms the relative magnitude vector represented by the specified
* {@code Point2D} instance by the inverse of this transform.
* The vector is transformed without applying the translation components
* of the affine transformation matrix.
* This method can be used only for a 2D transform.
* @param point the relative magnitude vector
* @return the inversely transformed relative magnitude vector represented
* by a {@code Point2D} instance
* @throws IllegalStateException if this is a 3D transform
* @throws NonInvertibleTransformException if this transform
* cannot be inverted
* @throws NullPointerException if the specified {@code point} is null
* @since JavaFX 8.0
*/
public Point2D inverseDeltaTransform(Point2D point)
throws NonInvertibleTransformException {
return inverseDeltaTransform(point.getX(), point.getY());
}
/**
* Transforms the relative magnitude vector by the inverse of this transform.
* The vector is transformed without applying the translation components
* of the affine transformation matrix.
* @param x vector magnitude in the direction of the X axis
* @param y vector magnitude in the direction of the Y axis
* @return the inversely transformed relative magnitude vector represented
* by a {@code Point3D} instance
* @throws NonInvertibleTransformException if this transform
* cannot be inverted
* @since JavaFX 8.0
*/
public Point3D inverseDeltaTransform(double x, double y, double z)
throws NonInvertibleTransformException {
return getInverseCache().deltaTransform(x, y, z);
}
/**
* Transforms the relative magnitude vector represented by the specified
* {@code Point3D} instance by the inverse of this transform.
* The vector is transformed without applying the translation components
* of the affine transformation matrix.
* @param point the relative magnitude vector
* @return the inversely transformed relative magnitude vector represented
* by a {@code Point3D} instance
* @throws NonInvertibleTransformException if this transform
* cannot be inverted
* @throws NullPointerException if the specified {@code point} is null
* @since JavaFX 8.0
*/
public Point3D inverseDeltaTransform(Point3D point)
throws NonInvertibleTransformException {
return inverseDeltaTransform(point.getX(), point.getY(), point.getZ());
}
/**
* Helper method for transforming arrays of points that deals with
* overlapping arrays.
* @return the (if necessary fixed) srcOff
*/
private int getFixedSrcOffset(double[] srcPts, int srcOff,
double[] dstPts, int dstOff,
int numPts, int dimensions) {
if (dstPts == srcPts &&
dstOff > srcOff && dstOff < srcOff + numPts * dimensions)
{
// If the arrays overlap partially with the destination higher
// than the source and we transform the coordinates normally
// we would overwrite some of the later source coordinates
// with results of previous transformations.
// To get around this we use arraycopy to copy the points
// to their final destination with correct overwrite
// handling and then transform them in place in the new
// safer location.
System.arraycopy(srcPts, srcOff, dstPts, dstOff, numPts * dimensions);
return dstOff;
}
return srcOff;
}
/* *************************************************************************
* *
* Event Dispatch *
* *
**************************************************************************/
private EventHandlerManager internalEventDispatcher;
private EventHandlerManager getInternalEventDispatcher() {
if (internalEventDispatcher == null) {
internalEventDispatcher = new EventHandlerManager(this);
}
return internalEventDispatcher;
}
private ObjectProperty* Registers an event handler to this transform. Any event filters are first * processed, then the specified onFoo event handlers, and finally any * event handlers registered by this method. *
* Currently the only event delivered to a {@code Transform} is the * {@code TransformChangedEvent} with it's single type * {@code TRANSFORM_CHANGED}. *
* * @param* Registers an event filter to this transform. Registered event filters get * an event before any associated event handlers. *
* Currently the only event delivered to a {@code Transform} is the * {@code TransformChangedEvent} with it's single type * {@code TRANSFORM_CHANGED}. *
*
* @param
* Gets the inverse transform cache.
*
* Computing the inverse transform is generally an expensive operation,
* so once it is needed we cache the result (throwing it away when the
* transform changes). The subclasses may avoid using the cache if their
* inverse can be computed quickly on the fly.
*
* This method computes the inverse if the cache is not valid.
*