//
// Control.java
//
/*
VisAD system for interactive analysis and visualization of numerical
data. Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
Tommy Jasmin.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA
*/
package visad;
import java.util.*;
import java.rmi.*;
/**
Control is the abstract VisAD superclass for controls for
DisplayRealTypes.
*/
public abstract class Control extends Object
implements Cloneable, java.io.Serializable {
/** incremented by incTick */
private long NewTick;
/** value of NewTick at last setTicks call */
private long OldTick;
/** set by setTicks if OldTick < NewTick; cleared by resetTicks */
private boolean tickFlag;
/** flag to indicate after setTicks and bfore resetTicks */
private boolean isSet = false;
/** unique Display this Control is part of */
transient DisplayImpl display;
transient DisplayRenderer displayRenderer;
/** index of this in display.ControlVector */
private int Index;
/** instance of this in display.ControlVector */
private int Instance;
/** Vector of ControlListeners */
private transient Vector ListenerVector = new Vector();
/**
* construct a Control for the given DisplayImpl
* @param d - DisplayImpl this Control is associated with
*/
public Control(DisplayImpl d) {
OldTick = Long.MIN_VALUE;
NewTick = Long.MIN_VALUE + 1;
tickFlag = false;
display = d;
Index = Instance = -1;
if (display != null) displayRenderer = display.getDisplayRenderer();
}
/**
* @return DisplayRenderer assciated with this Control
*/
public DisplayRenderer getDisplayRenderer() {
return displayRenderer;
}
/**
* invoked every time values of this Control change
* @param tick true to notify the Display for possible re-transform
*/
public void changeControl(boolean tick)
throws VisADException, RemoteException {
if (tick) incTick();
if (ListenerVector != null) {
Vector clv = null;
synchronized (ListenerVector) {
clv = (Vector) ListenerVector.clone();
}
Enumeration listeners = clv.elements();
while (listeners.hasMoreElements()) {
ControlListener listener =
(ControlListener) listeners.nextElement();
listener.controlChanged(new ControlEvent(this));
}
}
}
/**
* add a ControlListener
* @param listener ControlListener to add
*/
public void addControlListener(ControlListener listener) {
ListenerVector.addElement(listener);
}
/**
* remove a ControlListener
* @param listener ControlListener to remove
*/
public void removeControlListener(ControlListener listener) {
if (listener != null) {
ListenerVector.removeElement(listener);
}
}
/**
* end this control (called by ScalarMap.nullDisplay())
*/
public void nullControl() {
ListenerVector.removeAllElements();
}
/**
* increment long counter NewTick: NewTick > OldTick indicates
* that there is event in this Control that the DisplayImpl
* must process;
* this method is invoked every time Control changes
* @return incremented value of NewTick counter
*/
public long incTick() {
NewTick += 1;
if (NewTick == Long.MAX_VALUE) NewTick = Long.MIN_VALUE + 1;
if (display != null) display.controlChanged();
// System.out.println(getClass().getName() + " set NewTick = " + NewTick);
return NewTick;
}
/**
* set tickFlag if NewTick > OldTick, and reset OldTick = NewTick
* also invoke subSetTicks() to propagate to any sub-Controls
*/
public synchronized void setTicks() {
if (isSet) return; // WLH 22 Aug 99
isSet = true;
tickFlag = (OldTick < NewTick || (NewTick < 0 && 0 < OldTick));
// if (tickFlag) System.out.println(getClass().getName() + " set tickFlag = " + tickFlag);
OldTick = NewTick;
subSetTicks();
}
/**
* peek at future value of checkTicks()
* @param r DataRenderer to check if changes to this Control
* require re-transform
* @param link DataDisplayLink involved in decision whether
* changes to this Control require re-transform
* @return true if checkTicks() will return true after next setTicks()
*/
public synchronized boolean peekTicks(DataRenderer r, DataDisplayLink link) {
/*
boolean flag = (OldTick < NewTick || (NewTick < 0 && 0 < OldTick));
System.out.println(getClass().getName() + " peek flag = " + flag +
" trans = " + r.isTransformControl(this, link) + " sub = " +
subPeekTicks(r, link));
*/
return ((OldTick < NewTick || (NewTick < 0 && 0 < OldTick)) &&
r.isTransformControl(this, link)) || subPeekTicks(r, link);
}
/**
* check if this Control changed and requires re-Transform
* @param r DataRenderer to check if changes to this Control
* require re-transform
* @param link DataDisplayLink involved in decision whether
* changes to this Control require re-transform
* @return true if Control changed and requires re-Transform
*/
public synchronized boolean checkTicks(DataRenderer r, DataDisplayLink link) {
/*
boolean flag = (tickFlag && r.isTransformControl(this, link)) || subCheckTicks(r, link);
if (tickFlag) {
System.out.println(getClass().getName() + " check tickFlag = " + tickFlag +
" trans = " + r.isTransformControl(this, link) + " sub = " +
subCheckTicks(r, link));
}
*/
return (tickFlag && r.isTransformControl(this, link)) || subCheckTicks(r, link);
}
/**
* reset tickFlag and propagate to sub-Controls
*/
public synchronized void resetTicks() {
// if (tickFlag) System.out.println(getClass().getName() + " reset");
tickFlag = false;
subResetTicks();
isSet = false;
}
/**
* run setTicks on any sub-Controls;
* this default for no sub-Controls
*/
public void subSetTicks() {
}
/**
* run checkTicks on any sub-Controls
* this default for no sub-Controls
* @param r DataRenderer to check if changes to this Control
* require re-transform
* @param link DataDisplayLink involved in decision whether
* changes to this Control require re-transform
* @return 'logical or' of values from checkTicks on sub-Controls
*/
public boolean subCheckTicks(DataRenderer r, DataDisplayLink link) {
return false;
}
/**
* run peekTicks on any sub-Controls
* this default for no sub-Controls
* @param r DataRenderer to check if changes to this Control
* require re-transform
* @param link DataDisplayLink involved in decision whether
* changes to this Control require re-transform
* @return 'logical or' of values from peekTicks on sub-Controls
*/
public boolean subPeekTicks(DataRenderer r, DataDisplayLink link) {
return false;
}
/**
* run resetTicks on any sub-Controls
* this default for no sub-Controls
*/
public void subResetTicks() {
}
/**
* build String representation of current animation step
* and pass it to DisplayRenderer.setAnimationString()
* called by java3d.AnimationControlJ3D and java2d.AnimationControlJ2D
* @param real - RealType mapped to Display.Animation
* @param set - Set from AnimationSetControl
* @param value - real value associated with current animation step
* @param current - index of current animation step
* @throws VisADException a VisAD error occurred
*/
public void animation_string(RealType real, Set set, double value,
int current) throws VisADException {
if (set != null) {
Unit[] units = set.getSetUnits();
// WLH 31 Aug 2000
Vector tmap = display.getMapVector();
Unit overrideUnit = null;
for (int i=0; i pt) {
pt = ds;
}
if (pt == -1) {
pt = 0;
} else {
pt++;
}
return cn.substring(pt) + "@" + Index + "#" + Instance;
}
}
Ads help maintain this website.