alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (StateTrackableDelegate.java)

This example Java source code file (StateTrackableDelegate.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

cannot, dynamic, illegalstateexception, immutable, immutable_delegate, internalerror, stable, statetrackabledelegate, statetracker, untrackable, untrackable_delegate

The StateTrackableDelegate.java Java example source code

/*
 * Copyright (c) 2007, 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 sun.java2d;

import sun.java2d.StateTrackable.State;
import static sun.java2d.StateTrackable.State.*;

/**
 * This class provides a basic pre-packaged implementation of the
 * complete {@link StateTrackable} interface with implementations
 * of the required methods in the interface and methods to manage
 * transitions in the state of the object.
 * Classes which wish to implement StateTrackable could create an
 * instance of this class and delegate all of their implementations
 * for {@code StateTrackable} methods to the corresponding methods
 * of this class.
 */
public final class StateTrackableDelegate implements StateTrackable {
    /**
     * The {@code UNTRACKABLE_DELEGATE} provides an implementation
     * of the StateTrackable interface that is permanently in the
     * {@link State#UNTRACKABLE UNTRACKABLE} state.
     */
    public final static StateTrackableDelegate UNTRACKABLE_DELEGATE =
        new StateTrackableDelegate(UNTRACKABLE);

    /**
     * The {@code IMMUTABLE_DELEGATE} provides an implementation
     * of the StateTrackable interface that is permanently in the
     * {@link State#IMMUTABLE IMMUTABLE} state.
     */
    public final static StateTrackableDelegate IMMUTABLE_DELEGATE =
        new StateTrackableDelegate(IMMUTABLE);

    /**
     * Returns a {@code StateTrackableDelegate} instance with the
     * specified initial {@link State State}.
     * If the specified {@code State} is
     * {@link State#UNTRACKABLE UNTRACKABLE} or
     * {@link State#IMMUTABLE IMMUTABLE}
     * then the approprirate static instance
     * {@link #UNTRACKABLE_DELEGATE} or {@link #IMMUTABLE_DELEGATE}
     * is returned.
     */
    public static StateTrackableDelegate createInstance(State state) {
        switch (state) {
        case UNTRACKABLE:
            return UNTRACKABLE_DELEGATE;
        case STABLE:
            return new StateTrackableDelegate(STABLE);
        case DYNAMIC:
            return new StateTrackableDelegate(DYNAMIC);
        case IMMUTABLE:
            return IMMUTABLE_DELEGATE;
        default:
            throw new InternalError("unknown state");
        }
    }

    private State theState;
    StateTracker theTracker;   // package private for easy access from tracker
    private int numDynamicAgents;

    /**
     * Constructs a StateTrackableDelegate object with the specified
     * initial State.
     */
    private StateTrackableDelegate(State state) {
        this.theState = state;
    }

    /**
     * @inheritDoc
     * @since 1.7
     */
    public State getState() {
        return theState;
    }

    /**
     * @inheritDoc
     * @since 1.7
     */
    public synchronized StateTracker getStateTracker() {
        StateTracker st = theTracker;
        if (st == null) {
            switch (theState) {
            case IMMUTABLE:
                st = StateTracker.ALWAYS_CURRENT;
                break;
            case STABLE:
                st = new StateTracker() {
                    public boolean isCurrent() {
                        return (theTracker == this);
                    }
                };
                break;
            case DYNAMIC:
                // We return the NEVER_CURRENT tracker, but that is
                // just temporary while we are in the DYNAMIC state.
                // NO BREAK
            case UNTRACKABLE:
                st = StateTracker.NEVER_CURRENT;
                break;
            }
            theTracker = st;
        }
        return st;
    }

    /**
     * This method provides an easy way for delegating classes to
     * change the overall {@link State State} of the delegate to
     * {@link State#IMMUTABLE IMMUTABLE}.
     * @throws IllegalStateException if the current state is
     *         {@link State#UNTRACKABLE UNTRACKABLE}
     * @see #setUntrackable
     * @since 1.7
     */
    public synchronized void setImmutable() {
        if (theState == UNTRACKABLE || theState == DYNAMIC) {
            throw new IllegalStateException("UNTRACKABLE or DYNAMIC "+
                                            "objects cannot become IMMUTABLE");
        }
        theState = IMMUTABLE;
        theTracker = null;
    }

    /**
     * This method provides an easy way for delegating classes to
     * change the overall {@link State State} of the delegate to
     * {@link State#UNTRACKABLE UNTRACKABLE}.
     * This method is typically called when references to the
     * internal data buffers have been made public.
     * @throws IllegalStateException if the current state is
     *         {@link State#IMMUTABLE IMMUTABLE}
     * @see #setImmutable
     * @since 1.7
     */
    public synchronized void setUntrackable() {
        if (theState == IMMUTABLE) {
            throw new IllegalStateException("IMMUTABLE objects cannot "+
                                            "become UNTRACKABLE");
        }
        theState = UNTRACKABLE;
        theTracker = null;
    }

    /**
     * This method provides an easy way for delegating classes to
     * manage temporarily setting the overall {@link State State}
     * of the delegate to {@link State#DYNAMIC DYNAMIC}
     * during well-defined time frames of dynamic pixel updating.
     * This method should be called once before each flow of control
     * that might dynamically update the pixels in an uncontrolled
     * or unpredictable fashion.
     * <p>
     * The companion method {@link #removeDynamicAgent} method should
     * also be called once after each such flow of control has ended.
     * Failing to call the remove method will result in this object
     * permanently becoming {@link State#DYNAMIC DYNAMIC}
     * and therefore effectively untrackable.
     * <p>
     * This method will only change the {@link State State} of the
     * delegate if it is currently {@link State#STABLE STABLE}.
     *
     * @throws IllegalStateException if the current state is
     *         {@link State#IMMUTABLE IMMUTABLE}
     * @since 1.7
     */
    public synchronized void addDynamicAgent() {
        if (theState == IMMUTABLE) {
            throw new IllegalStateException("Cannot change state from "+
                                            "IMMUTABLE");
        }
        ++numDynamicAgents;
        if (theState == STABLE) {
            theState = DYNAMIC;
            theTracker = null;
        }
    }

    /**
     * This method provides an easy way for delegating classes to
     * manage restoring the overall {@link State State} of the
     * delegate back to {@link State#STABLE STABLE}
     * after a well-defined time frame of dynamic pixel updating.
     * This method should be called once after each flow of control
     * that might dynamically update the pixels in an uncontrolled
     * or unpredictable fashion has ended.
     * <p>
     * The companion method {@link #addDynamicAgent} method should
     * have been called at some point before each such flow of
     * control began.
     * If this method is called without having previously called
     * the add method, the {@link State State} of this object
     * will become unreliable.
     * <p>
     * This method will only change the {@link State State} of the
     * delegate if the number of outstanding dynamic agents has
     * gone to 0 and it is currently
     * {@link State#DYNAMIC DYNAMIC}.
     *
     * @since 1.7
     */
    protected synchronized void removeDynamicAgent() {
        if (--numDynamicAgents == 0 && theState == DYNAMIC) {
            theState = STABLE;
            theTracker = null;
        }
    }

    /**
     * This method provides an easy way for delegating classes to
     * indicate that the contents have changed.
     * This method will invalidate outstanding StateTracker objects
     * so that any other agents which maintain cached information
     * about the pixels will know to refresh their cached copies.
     * This method should be called after every modification to
     * the data, such as any calls to any of the setElem methods.
     * <p>
     * Note that, for efficiency, this method does not check the
     * {@link State State} of the object to see if it is compatible
     * with being marked dirty
     * (i.e. not {@link State#IMMUTABLE IMMUTABLE}).
     * It is up to the callers to enforce the fact that an
     * {@code IMMUTABLE} delegate is never modified.
     * @since 1.7
     */
    public final void markDirty() {
        theTracker = null;
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java StateTrackableDelegate.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.