Package org.jdesktop.wonderland.modules.hud.client

Source Code of org.jdesktop.wonderland.modules.hud.client.HUDObject2D

/*
* Project Wonderland
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., All Rights Reserved
*
* Redistributions in source code form must reproduce the above
* copyright and this condition.
*
* The contents of this file are subject to the GNU General Public
* License, Version 2 (the "License"); you may not use this file
* except in compliance with the License. A copy of the License is
* available at http://www.opensource.org/licenses/gpl-license.php.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied
* this code.
*/
package org.jdesktop.wonderland.modules.hud.client;

import com.jme.math.Vector3f;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
import java.util.Date;
import java.util.Iterator;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.logging.Logger;
import javax.swing.ImageIcon;
import javax.swing.SwingUtilities;
import org.jdesktop.wonderland.client.hud.CompassLayout.Layout;
import org.jdesktop.wonderland.client.hud.HUDEvent;
import org.jdesktop.wonderland.client.hud.HUDEvent.HUDEventType;
import org.jdesktop.wonderland.client.hud.HUDEventListener;
import org.jdesktop.wonderland.client.hud.HUDObject;
import org.jdesktop.wonderland.modules.animationbase.client.interpolators.FloatInterpolator;

/**
* A rectangular 2D visual object.
*
* @author nsimpson
*/
public class HUDObject2D implements HUDObject {

    private static final Logger logger = Logger.getLogger(HUDObject2D.class.getName());
    protected String name;
    protected Rectangle2D bounds;       // on-HUD position
    protected Vector3f worldLocation;   // in-world position
    protected DisplayMode mode = DisplayMode.HUD;
    protected boolean visible = false;
    protected boolean worldVisible = false;
    protected float preferredTransparency = 1.0f;
    protected float transparency = preferredTransparency;
    protected Thread animationThread;
    protected HUDAnimator animator;
    protected boolean enabled = false;
    protected boolean minimized = false;
    protected boolean decoratable = true;
    protected ImageIcon iconImage;
    protected Layout compassPoint = Layout.NONE;
    protected ConcurrentLinkedQueue<HUDEventListener> listeners;
    private ConcurrentLinkedQueue<HUDEvent> eventQueue;
    private boolean notifying = false;
    private int id;

    public HUDObject2D() {
        listeners = new ConcurrentLinkedQueue();
        eventQueue = new ConcurrentLinkedQueue();
        bounds = new Rectangle2D.Double();
        id = new Random().nextInt(10000);
    }

    /**
     * {@inheritDoc}
     */
    public void setName(String name) {
        this.name = name;

        notifyEventListeners(HUDEventType.CHANGED_NAME);
    }

    /**
     * {@inheritDoc}
     */
    public String getName() {
        return name;
    }

    /**
     * {@inheritDoc}
     */
    public void setWidth(int width) {
        bounds.setRect(bounds.getX(), bounds.getY(), width, bounds.getHeight());

        notifyEventListeners(HUDEventType.RESIZED);
    }

    /**
     * {@inheritDoc}
     */
    public int getWidth() {
        return (int) bounds.getWidth();
    }

    /**
     * {@inheritDoc}
     */
    public void setHeight(int height) {
        bounds.setRect(bounds.getX(), bounds.getY(), bounds.getWidth(), height);

        notifyEventListeners(HUDEventType.RESIZED);
    }

    /**
     * {@inheritDoc}
     */
    public int getHeight() {
        return (int) bounds.getHeight();
    }

    /**
     * {@inheritDoc}
     */
    public void setSize(int width, int height) {
        bounds.setRect(bounds.getX(), bounds.getY(), width, height);

        notifyEventListeners(HUDEventType.RESIZED);
    }

    /**
     * {@inheritDoc}
     */
    public void setSize(Dimension dimension) {
        bounds.setRect(bounds.getX(), bounds.getY(), dimension.getWidth(), dimension.getHeight());

        notifyEventListeners(HUDEventType.RESIZED);
    }

    /**
     * {@inheritDoc}
     */
    public Dimension getSize() {
        return new Dimension((int) bounds.getWidth(), (int) bounds.getHeight());
    }

    /**
     * {@inheritDoc}
     */
    public void setBounds(Rectangle bounds) {
        this.bounds = bounds;

        notifyEventListeners(HUDEventType.RESIZED);
    }

    /**
     * {@inheritDoc}
     */
    public void setBounds(int x, int y, int width, int height) {
        setBounds(new Rectangle(x, y, width, height));
    }

    /**
     * {@inheritDoc}
     */
    public Rectangle getBounds() {
        return bounds.getBounds();
    }

    /**
     * {@inheritDoc}
     */
    public void setX(int x) {
        bounds.setRect(x, bounds.getY(), bounds.getWidth(), bounds.getHeight());

        notifyEventListeners(HUDEventType.MOVED);
    }

    /**
     * {@inheritDoc}
     */
    public int getX() {
        return (int) bounds.getX();
    }

    /**
     * {@inheritDoc}
     */
    public void setY(int y) {
        bounds.setRect(bounds.getX(), y, bounds.getWidth(), bounds.getHeight());

        notifyEventListeners(HUDEventType.MOVED);
    }

    /**
     * {@inheritDoc}
     */
    public int getY() {
        return (int) bounds.getY();
    }

    /**
     * {@inheritDoc}
     */
    public void setLocation(int x, int y) {
        setLocation(x, y, true);
    }

    /**
     * {@inheritDoc}
     */
    public void setLocation(int x, int y, boolean notify) {
        bounds.setRect(x, y, bounds.getWidth(), bounds.getHeight());

        if (notify) {
            notifyEventListeners(HUDEventType.MOVED);
        }
    }

    /**
     * {@inheritDoc}
     */
    public void setLocation(Point p) {
        setLocation(p.x, p.y);
    }

    /**
     * {@inheritDoc}
     */
    public Point getLocation() {
        return new Point((int) bounds.getX(), (int) bounds.getY());
    }

    /**
     * {@inheritDoc}
     */
    public void setPreferredLocation(Layout compassPoint) {
        this.compassPoint = compassPoint;
    }

    /**
     * {@inheritDoc}
     */
    public Layout getPreferredLocation() {
        return compassPoint;
    }

    /**
     * {@inheritDoc}
     */
    public void setWorldLocation(Vector3f location) {
        this.worldLocation = location;

        notifyEventListeners(HUDEventType.MOVED_WORLD);
    }

    /**
     * {@inheritDoc}
     */
    public Vector3f getWorldLocation() {
        return worldLocation;
    }

    /**
     * {@inheritDoc}
     */
    public void setVisible(boolean visible) {
        if (this.visible == visible) {
            return;
        }
        this.visible = visible;

        notifyEventListeners((visible == true) ? HUDEventType.APPEARED
                : HUDEventType.DISAPPEARED);
    }

    /**
     * {@inheritDoc}
     */
    public void setVisible(final boolean visible, final long when) {
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                Timer t = new Timer();
                t.schedule(new VisibilityTask(DisplayMode.HUD, visible), when);
            }
        });
    }

    private class VisibilityTask extends TimerTask {

        private boolean visible = true;
        private DisplayMode mode;

        public VisibilityTask(DisplayMode mode, boolean visible) {
            this.mode = mode;
            this.visible = visible;
        }

        public void run() {
            if (mode == DisplayMode.HUD) {
                setVisible(visible);
            } else if (mode == DisplayMode.WORLD) {
                setWorldVisible(visible);
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    public boolean isVisible() {
        return visible;
    }

    /**
     * {@inheritDoc}
     */
    public void setWorldVisible(boolean worldVisible) {
        if (this.worldVisible == worldVisible) {
            return;
        }
        this.worldVisible = worldVisible;

        notifyEventListeners((worldVisible == true) ? HUDEventType.APPEARED_WORLD
                : HUDEventType.DISAPPEARED_WORLD);
    }

    /**
     * {@inheritDoc}
     */
    public void setWorldVisible(final boolean worldVisible, final long when) {
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                Timer t = new Timer();
                t.schedule(new VisibilityTask(DisplayMode.WORLD, worldVisible), when);
            }
        });
    }

    /**
     * {@inheritDoc}
     */
    public boolean isWorldVisible() {
        return worldVisible;
    }

    /**
     * {@inheritDoc}
     */
    public void setClosed() {
        notifyEventListeners(HUDEventType.CLOSED);
    }

    /**
     * {@inheritDoc}
     */
    public void setDisplayMode(DisplayMode mode) {
        this.mode = mode;

        notifyEventListeners(HUDEventType.CHANGED_MODE);
    }

    /**
     * {@inheritDoc}
     */
    public DisplayMode getDisplayMode() {
        return mode;
    }

    /**
     * {@inheritDoc}
     */
    public void setPreferredTransparency(Float preferredTransparency) {
        this.preferredTransparency = preferredTransparency;
    }

    /**
     * {@inheritDoc}
     */
    public float getPreferredTransparency() {
        return preferredTransparency;
    }

    /**
     * {@inheritDoc}
     */
    public void setTransparency(Float transparency) {
        this.transparency = transparency;

        notifyEventListeners(HUDEventType.CHANGED_TRANSPARENCY);
    }

    /**
     * {@inheritDoc}
     */
    public float getTransparency() {
        return transparency;
    }

    /**
     * {@inheritDoc}
     */
    public void changeTransparency(Float from, Float to) {
        changeTransparency(from, to, HUDAnimator.DEFAULT_DURATION);
    }

    /**
     * {@inheritDoc}
     */
    public void changeTransparency(Float from, Float to, long duration) {
        if ((animator != null) && (animator.isAnimating())) {
            animator.cancel();
            animator = null;
            animationThread = null;
        }
        animator = new HUDAnimator(this, "transparency", new FloatInterpolator(), from, to, duration);
        animationThread = new Thread(animator);
        animationThread.start();
    }

    /**
     * {@inheritDoc}
     */
    public void setEnabled(boolean enabled) {
        if (this.enabled == enabled) {
            return;
        }
        this.enabled = enabled;

        notifyEventListeners((enabled == true) ? HUDEventType.ENABLED
                : HUDEventType.DISABLED);
    }

    /**
     * {@inheritDoc}
     */
    public boolean isEnabled() {
        return enabled;
    }

    /**
     * {@inheritDoc}
     */
    public void setMinimized() {
        if (minimized == true) {
            return;
        }
        minimized = true;

        notifyEventListeners(HUDEventType.MINIMIZED);
    }

    /**
     * {@inheritDoc}
     */
    public void setMaximized() {
        if (minimized == false) {
            return;
        }
        minimized = false;

        notifyEventListeners(HUDEventType.MAXIMIZED);
    }

    /**
     * {@inheritDoc}
     */
    public boolean isMinimized() {
        return minimized;
    }

    /**
     * {@inheritDoc}
     */
    public void setDecoratable(boolean decoratable) {
        this.decoratable = decoratable;
    }

    /**
     * {@inheritDoc}
     */
    public boolean getDecoratable() {
        return decoratable;
    }

    /**
     * {@inheritDoc}
     */
    public void setIcon(ImageIcon iconImage) {
        this.iconImage = iconImage;
    }

    /**
     * {@inheritDoc}
     */
    public ImageIcon getIcon() {
        return iconImage;
    }

    /**
     * {@inheritDoc}
     */
    public boolean hasControl() {
        return true;
    }

    /**
     * {@inheritDoc}
     */
    public void addEventListener(HUDEventListener listener) {
        listeners.add(listener);
        logger.finest(this.getClass().getSimpleName() + " added event listener: " + listener.getClass().getSimpleName() + ", " + listeners.size() + " listeners");
        // TODO: notify the new listener that the component was created?
    }

    /**
     * {@inheritDoc}
     */
    public void removeEventListener(HUDEventListener listener) {
        listeners.remove(listener);
    }

    /**
     * {@inheritDoc}
     */
    public HUDEventListener[] getEventListeners() {
        return listeners.toArray(new HUDEventListener[0]);
    }

    /**
     * {@inheritDoc}
     */
    public void notifyEventListeners(final HUDEvent e) {
        if (listeners != null) {
            eventQueue.add(new HUDEvent(e));
            if (notifying) {
                // already notifying, let the current notification loop handle
                // this new event as well
                return;
            } else {
                notifying = true;
            }

            //logger.finest("=== [" + id + "] START notifying listeners");

            while (!eventQueue.isEmpty()) {
                HUDEvent ev = (HUDEvent) eventQueue.remove();
                //HUDEventType type = ev.getEventType();
                Iterator<HUDEventListener> iterator = listeners.iterator();
                //int num = listeners.size();
                //int i = 1;
                while (iterator.hasNext()) {
                    HUDEventListener notifiee = iterator.next();
                    //logger.finest("   === [" + id + "] " + i + "/" + num + ": sending " + type + " to " + notifiee.getClass().getSimpleName());
                    //i++;
                    notifiee.HUDObjectChanged(ev);
                }
                iterator = null;
                ev = null;
            }

            //logger.finest("=== [" + id + "] DONE notifying listeners: " + eventQueue.size());
            notifying = false;
        }
    }

    /**
     * Convenience methods for notifying listeners
     * @param eventType the type of the notification event
     */
    public void notifyEventListeners(HUDEventType eventType) {
        notifyEventListeners(new HUDEvent(this, eventType, new Date()));
    }

    @Override
    public String toString() {
        return "HUDObject2D: " + id +
                ", bounds: " + bounds +
                ", mode: " + mode +
                ", visible: " + visible +
                ", world visible: " + worldVisible +
                ", enabled: " + enabled +
                ", transparency: " + transparency +
                ", decoratable: " + decoratable;
    }
}
TOP

Related Classes of org.jdesktop.wonderland.modules.hud.client.HUDObject2D

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.