home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Best Tools for JAVA
/
Best Tools for JAVA.iso
/
JAVA_ALL
/
IDE
/
SUBARTIC
/
RELEASE.ZIP
/
sub_arctic
/
lib
/
manager.java
< prev
next >
Encoding:
Amiga
Atari
Commodore
DOS
FM Towns/JPY
Macintosh
Macintosh JP
Macintosh to JP
NeXTSTEP
RISC OS/Acorn
Shift JIS
UTF-8
Wrap
Java Source
|
1996-10-04
|
70.9 KB
|
1,926 lines
package sub_arctic.lib;
/* we import every policy and agent from input so we might as well
* take the whole works. */
import sub_arctic.input.*;
import sub_arctic.anim.animation_agent;
import sub_arctic.constraints.value_provider;
import sub_arctic.constraints.value_consumer;
import sub_arctic.constraints.provider_part_ref;
import sub_arctic.constraints.consumer_part_ref;
import sub_arctic.output.ignore_observer;
import sub_arctic.output.loaded_image;
import sub_arctic.output.drawable;
import sub_arctic.output.color_pair;
import sub_arctic.output.color_scheme;
import sub_arctic.output.style_manager;
import java.util.Vector;
import java.util.Hashtable;
import java.awt.Toolkit;
import java.awt.Component;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Color;
import java.awt.Event;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.image.ImageObserver;
import java.awt.image.ImageProducer;
import java.awt.image.MemoryImageSource;
import java.applet.Applet;
import java.net.URL;
import java.net.MalformedURLException;
import java.io.IOException;
import java.io.PrintStream;
/**
* This class provides overall coordination and management functions for the
* toolkit as well as providing a series of utility functions, and functions
* that isolate the interface to AWT. This class contains only static
* members and methods and is never actually instantiated.
*
* @author Scott Hudson
*/
public class manager {
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Constructor is private so we get no instances of this class (everything
* is static).
*/
private manager() { }
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/** Set of all input dispatch policies. */
protected static Vector _policy_list;
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/** Flag indicating something somewhere is damaged. */
protected static boolean _something_is_damaged = true;
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/** Set of all top level interactor objects in the system. */
protected static Vector _top_level_interactors;
// this is currently not used, but we may want a redraw_all later
/** Set of all AWT components that top_level interactors are hosted by.
* Note: this list is not synchronized with the list of top level
* interactors.
*/
protected static Vector _all_awt_components;
/** Set of all AWT applets that top_level interactors are hosted by.
* Note: this list is not synchronized with the list of top level
* interactors or the list of awt components.
*/
protected static Vector _all_applets;
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/** Reference to a toolkit object that we can use to create things. */
protected static Toolkit _default_toolkit;
/**
* Get a reference the default native toolkit object. This object is
* useful for getting low level access to toolkit capabilities. However,
* the manager provides interfaces for most object types of general
* interest, so this object will probably be rarely used outside the
* manager itself.
*
* @return Toolkit the default native toolkit object.
*/
public static Toolkit default_toolkit() {return _default_toolkit;}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Lookup table for storage of notify lists on behalf of interactors (this
* is part of the "external" or "heavyweight" constraint system).
* This is indexed by provider_part_ref's and contains Vectors of
* consumer_part_ref's.
*/
protected static Hashtable _notify_list_table;
/**
* Lookup table for associating external constraints with interactors.
* This is indexed by consumer_part_ref's and contains provider_part_ref's.
*/
protected static Hashtable _extern_constraints_table;
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/* Static initialization */
static
{
_something_is_damaged = true;
_policy_list = new Vector();
install_standard_policies();
_top_level_interactors = new Vector();
_all_awt_components = new Vector();
_all_applets = new Vector();
_notify_list_table = new Hashtable();
_extern_constraints_table = new Hashtable();
_default_toolkit = Toolkit.getDefaultToolkit();
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/* Policies and Agents */
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Monitor focus input policy. This policy is focus based (it passes inputs
* to objects which have established themselves as the focus) but is set
* up to monitor events only, not consume them. This is useful for things
* like creating new kinds of cursors, where we need to know the position
* of events, but still want them delivered elsewhere.
*/
public static mon_focus_policy_class monitor_focus_policy;
/**
* Event trace dispatch agent. This agent works under the monitor focus
* input delivery policy and prints a human readable trace of events as
* they arrive (for debugging purposes), but does not actually distribute
* them anywhere. Trace printing is off by default. To start tracing
* send the message do_trace(true) to this object.
*/
public static event_trace_agent event_tracer;
/**
* Monitor version of raw focus dispatch agent. This agent works under
* the monitor focus policy and delivers raw events to requesting objects.
* This is here primarily as a hook for implementing unusual actions
* (although a lot of things it might be used for are probably better
* handled by adding new policies and/or agents, so you might want to
* consider that before building something with this).
*/
public static raw_focus_agent raw_monitor;
/**
* Click tracker. This agent allows an object to monitor mouse button
* state outside its normal domain (to for example realize that the
* release matching a previous press will never arrive since it was
* delivered somewhere else). This agent works with click_tracking
* objects and only delivers input resulting from MOUSE_UP, and
* MOUSE_DOWN events.
*/
public static click_track_agent click_tracker;
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Focus input policy. This policy delivers inputs to objects which have
* made themselves the focus of various kinds of inputs (rather than, for
* example positionally -- based on the mouse position at the time of the
* event).
*/
public static focus_policy_class focus_policy;
/**
* Raw input event focus dispatch agent. This agent works under
* the focus policy and delivers raw events to requesting objects.
* This is here primarily as a hook for implementing unusual actions
* (although a lot of things it might be used for are probably better
* handled by adding new policies and/or agents, so you might want to
* consider that before building something with this).
*/
public static raw_focus_agent raw_focus;
/** Simple drag focus agent. */
public static simple_drag_focus_agent simple_drag_focus;
/** Move-drag focus agent. */
public static move_drag_focus_agent move_drag_focus;
/** Grow-drag focus agent. */
public static grow_drag_focus_agent grow_drag_focus;
/** Snap-drag focus agent. */
public static snap_drag_agent snap_drag_focus;
/** Inout drag focus agent. */
public static inout_drag_focus_agent inout_drag_focus;
/** Text focus agent. */
public static text_focus_agent text_focus;
/**
* This is the agent for handling the work procedures set up
* for doing multithreaded programming.
*/
public static work_agent work;
/**
* Animation agent.
* This agent handles the scheduling of animation events (via its
* 'transitions' notion to interested interactors. It will deliver
* these events to any interactor scheduling a transition, independent
* of other factors such as visibility, being connected to the
* tree, etc.
*/
public static animation_agent animation;
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Positional input policy. This policy delivers inputs to objects which
* are found under the cursor.
*/
public static positional_policy_class positional_policy;
/**
* Raw input event positional dispatch agent. This agent works under
* the positional policy and delivers raw events to objects under the
* cursor. This is here primarily as a hook for implementing unusual
* actions (although a lot of things it might be used for are probably
* better handled by adding new policies and/or agents, so you might want to
* consider that before building something with this).
*/
public static raw_positional_agent raw_positional;
/**
* Agent that combines press and move_drag. This is a hybrid policy
* that accepts press then makes the object it would have been delivered
* to the move_drag focus.
*/
public static move_press_drag_agent move_press_drag;
/**
* Agent that combines press and grow_drag. This is a hybrid policy
* that accepts press then makes the object it would have been delivered
* to the grow_drag focus.
*/
public static grow_press_drag_agent grow_press_drag;
/**
* Agent for inout_press_dragging. This is a hybrid policy that accepts
* press then makes the object it would have been delivered to the
* inout_drag focus.
*/
public static inout_press_drag_agent inout_press_drag;
/**
* Agent that combines press and simple_drag . This is a hybrid policy
* that accepts press then makes the object it would have been delivered
* to the simple_drag focus.
*/
public static simple_press_drag_agent simple_press_drag;
/** Agent for pressable, clickable, and double_clickable. */
public static click_agent press_click_agent;
/** Agent for maintaining a currently selected set with mouse presses */
public static selection_agent_class selection_agent;
/**
* Agent that handles the pointable protocol for telling
* when objects are entered or exited.
*/
public static point_agent_class point_agent;
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
protected static void install_standard_policies()
{
/*----------------------*/
/* monitor focus policy */
/*----------------------*/
monitor_focus_policy = new mon_focus_policy_class();
install_policy_after(monitor_focus_policy, null);
/* monitor agents */
/* event tracer that just prints a debug trace of events */
event_tracer = new event_trace_agent();
monitor_focus_policy.add_agent_after(event_tracer, null);
/* agent for tracking mouse state changes anywhere */
click_tracker = new click_track_agent();
monitor_focus_policy.add_agent_after(click_tracker, null);
/* raw focus to use as a hook for extensions */
raw_monitor = new raw_focus_agent();
monitor_focus_policy.add_agent_after(raw_monitor, null);
/*-----------------------*/
/* (normal) focus policy */
/*-----------------------*/
focus_policy = new focus_policy_class();
install_policy_after(focus_policy, null);
/* focus agents */
/* raw focus to use as a hook for extensions */
raw_focus = new raw_focus_agent();
focus_policy.add_agent_after(raw_focus, null);
/* simple drag focus */
simple_drag_focus = new simple_drag_focus_agent();
focus_policy.add_agent_after(simple_drag_focus, null);
/* move-drag focus */
move_drag_focus = new move_drag_focus_agent();
focus_policy.add_agent_after(move_drag_focus, null);
/* grow-drag focus */
grow_drag_focus = new grow_drag_focus_agent();
focus_policy.add_agent_after(grow_drag_focus, null);
/* snap-drag focus */
snap_drag_focus = new snap_drag_agent();
focus_policy.add_agent_after(snap_drag_focus, null);
/* inout drag focus */
inout_drag_focus = new inout_drag_focus_agent();
focus_policy.add_agent_after(inout_drag_focus, null);
/* text focus */
text_focus = new text_focus_agent();
focus_policy.add_agent_after(text_focus, null);
/* add an animation agent */
animation = new animation_agent();
focus_policy.add_agent_after(animation,null);
/* work proc */
work=new work_agent();
focus_policy.add_agent_after(work,null);
/*-------------------*/
/* positional policy */
/*-------------------*/
positional_policy = new positional_policy_class();
install_policy_after(positional_policy, null);
/* positional agents */
/* raw positional to use as a hook for extensions */
raw_positional = new raw_positional_agent();
positional_policy.add_agent_after(raw_positional, null);
/* move_press_drag agent */
move_press_drag = new move_press_drag_agent();
positional_policy.add_agent_after(move_press_drag, null);
/* grow_press_drag agent */
grow_press_drag = new grow_press_drag_agent();
positional_policy.add_agent_after(grow_press_drag, null);
/* inout version of press_drag */
inout_press_drag = new inout_press_drag_agent();
positional_policy.add_agent_after(inout_press_drag, null);
/* simple_press_drag agent */
simple_press_drag = new simple_press_drag_agent();
positional_policy.add_agent_after(simple_press_drag, null);
/** object that does press, click, and double-click */
press_click_agent = new click_agent();
positional_policy.add_agent_after(press_click_agent, null);
/** currently selected set agent */
selection_agent = new selection_agent_class();
positional_policy.add_agent_after(selection_agent, null);
/* The agent for handling the pointable interface */
point_agent=new point_agent_class();
positional_policy.add_agent_after(point_agent,null);
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Install a new policy after an existing one (or at the end of the
* policy list).
* @param input_policy add the policy to add.
* @param input_policy after the policy to put it after. If this is null, we
* install at the end of the list.
*/
public static void install_policy_after(
input_policy add,
input_policy after)
{
/* if we have nothing to go after put it at the end */
if (after == null)
_policy_list.addElement(add);
else
{
int indx = _policy_list.indexOf(after);
if (indx < 0)
/* no such policy -- throw an exception */
throw new sub_arctic_error(
"Attempt to install input policy after uninstalled policy");
else
/* put it right after the one given */
_policy_list.insertElementAt(add, indx+1);
}
}
//had:
//* @exception bad_value if after refers to a policy that's not installed in
//* the policy list.
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Install a new policy before an existing one (or at the beginning of the
* policy list).
* @param input_policy add the policy to add.
* @param input_policy after the policy to put it before. If this is null, we
* install at the beginning of the list.
*/
public static void install_policy_before(
input_policy add,
input_policy before)
{
/* if we have nothing to go before put it at the beginning */
if (before == null)
_policy_list.insertElementAt(add,0);
else
{
int indx = _policy_list.indexOf(before);
if (indx < 0)
/* no such policy -- throw an exception */
throw new sub_arctic_error(
"Attempt to install input policy before uninstalled policy");
else
/* put it right before the one given */
_policy_list.insertElementAt(add, indx);
}
}
//had:
//*@exception bad_value if before refers to a policy that's not installed in
//* the policy list.
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Add a top_level object to the set of active top_level objects.
* @param top_level int_obj the top_level interactor to add.
*/
public static void add_top_level(top_level int_obj)
{
/* add it to our list */
_top_level_interactors.addElement(int_obj);
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Remove a top_level object from the set of active top_level objects.
* @param top_level int_obj the top_level interactor to remove.
*/
public static void remove_top_level(top_level int_obj)
{
_top_level_interactors.removeElement(int_obj);
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Indicate that an AWT component that will be hosting a sub_arctic
* top_level object has been created.
* @param Component awt_comp the host component.
*/
public static void register_awt_component(Component awt_comp)
{
/* record the component */
_all_awt_components.addElement(awt_comp);
/* walk up the parent chain to find and record the hosting applet */
for (Component c = awt_comp; c != null; c = c.getParent())
if (c instanceof Applet)
{
_all_applets.addElement(c);
break;
}
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Indicate that an AWT component that has been hosting a sub_arctic
* top_level object is not longer doing so.
* @param Component awt_comp the component that is no longer a host.
*/
public static void unregister_awt_component(Component awt_comp)
{
_all_awt_components.removeElement(awt_comp);
/* walk up the parent chain to find and remove the hosting applet */
for (Component c = awt_comp; c != null; c = c.getParent())
if (c instanceof Applet)
{
_all_applets.removeElement(c);
break;
}
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Indicate whether there is something in the system that is damaged and
* needs to be redrawn.
* @returns boolean true if there is unfixed damage pending.
*/
public static boolean something_is_damaged()
{
return _something_is_damaged;
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Report to the system that a top_level object has recorded some damage that
* requires it to be redrawn. This report gets passed on to AWT so that
* it schedules an update/repaint.
*
* @param top_level from_obj the object reporting the damage.
*/
public static void report_damage(top_level from_obj)
{
_something_is_damaged = true;
if (from_obj.awt_parent() != null)
from_obj.awt_parent().repaint();
// look into this again later:
// we may want to batch up these calls to repaint rather than make them
// every time we get damage
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* This is a list of dispatch_agents who would like to be informed
* whenever an event was successfully dispatched. This is important for
* agents which need to update their state machines on the next
* event regardless of who dispatched it
*/
protected static Vector after_dispatch = new Vector(10);
/**
* Add an agent to the list of agents interested in the after dispatch hook.
*
* @param dispatch_agent agent the agent to add to the list of interested
* agents.
*/
public static void add_to_after_dispatch_list(dispatch_agent agent) {
/* don't bother adding more than once */
if (after_dispatch.contains(agent)) return;
/* put it in */
after_dispatch.addElement(agent);
}
/**
* Remove an agent from the list of dispatch_agents which are
* interested in the after dispatch hook. Attempting to remove
* an agent which is not in the list has no effect.
* @param dispatch_agent agent the agent to remove.
*/
public static void remove_from_after_dispatch_list(dispatch_agent agent){
/* the vector does what we want here */
after_dispatch.removeElement(agent);
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Counter for event sequence numbers. This is incremented for each
* new event. These sequence numbers are used by some parts of the system
* to determine when cached values associated with one event dispatch are
* invalid.
*/
protected static int _event_seq_num = 0;
/**
* Return the sequence number for the current event. This is used by
* some parts of the system to determine when cached values associated with
* one event dispatch are invalid.
*
* @return int the sequence number for the current event.
*/
public static int event_seq_num() {return _event_seq_num;}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* This method dispatches a single event (that occurred "inside of" the
* given top level object) to the appropriate interactor object(s) in the
* interface. Note: that the event is not necessarily delivered to an
* object in the subtree rooted by top_obj -- this depends on the input
* policy object which ends up dispatching it. For example, the focus
* policy will send a key press event to the current text focus object
* regardless of where the mouse it pointing.<p>
*
* Note: this method is synchronized so that only one event dispatch or
* redraw can be going on at a time. This is necessary for maintaining
* the integrity of the overall system dispatch-redraw "loop". However,
* this is not sufficient to make the whole system thread-safe. Access to
* various interactor trees should always be done through the work_proc
* interface.
*
* @param Event evt the event to dispatch.
* @param top_level the top_level object it occured within.
*/
public static synchronized boolean dispatch_event(Event evt,top_level top_obj)
{
event our_event;
input_policy policy;
dispatch_agent agent;
boolean ret_val = false; /* we change this if someone dispatches */
/* increment the sequence number so caches get invalidated as needed */
_event_seq_num++;
/* create a sub_arctic event out of the awt event */
our_event = new event(evt,top_obj);
/* walk down the dispatch policy list */
for (int i = 0; i < _policy_list.size(); i++)
{
/* try to dispatch with the policy. if it succeeds, we are done. */
policy = (input_policy)_policy_list.elementAt(i);
if (policy.dispatch_event(our_event)) {
ret_val=true;
break;
}
}
/* walk through the list of after_dispatch agents */
for (int i=0; i<after_dispatch.size(); ++i){
agent=(dispatch_agent)after_dispatch.elementAt(i);
agent.after_dispatch_notify(our_event,ret_val);
}
/* if nobody wanted it, this will still be false */
return ret_val;
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* This method causes a redraw of the given interactor tree (this is
* normally called on the basis of a redraw request from AWT). A redraw
* request is handled by first laying out the objects in the interactor
* tree by calling configure() on the root (note: for the most part, this
* normally results in evaluating all the constraints that size and position
* objects in the tree). After all objects have been properly laid out,
* (which may cause additional areas of the drawable to become damaged)
* the smallest rectangle enclosing the damaged regions -- that is the
* regions which might have changed appearance in some way -- are redrawn
* by calling draw_self on the root of the tree.<p>
*
* Note: this method is synchronized so that only one event dispatch or
* redraw can be going on at a time. This is necessary for maintaining
* the integrity of the overall system dispatch-redraw "loop". However,
* this is not sufficient to make the whole system thread-safe. Access to
* various interactor trees should always be done through the work_proc
* interface.
*
* @param top_level top_obj the top_level object to redraw.
* @param drawable surface the drawing surface to redraw it on (this
* normally refers directly to the screen).
*/
public static synchronized void do_redraw(top_level top_obj, drawable surface)
{
top_obj.configure();
top_obj.draw_self(surface);
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* An ImageObserver object that does nothing. This is returned by
* an_observer() and used internally by the system to provide an
* observer object where we don't really need or want to observe.
*/
protected static ImageObserver _an_observer = new ignore_observer();
/**
* Return an ImageObserver that does nothing. This is useful in places
* where an ImageObserver object is needed, but we don't really expect
* to see any updates (and/or wouldn't know what to do with them if we
* got them).
*
* @return ImageObserver a non-observing observer object.
*/
public static ImageObserver an_observer() {return _an_observer;}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Return some active AWT component. Most code outside the toolkit itself
* should not need this, but it can be useful in various AWT routines that
* require some component to get a piece of information (some of this is now
* provided by a toolkit object obtained by default_toolkit() but not
* everything). If a specific component is needed, use
* interactor.get_awt_component() instead.
*
* @return Component an AWT Component object which is currently hosting a
* subArctic interface (or null if there currently are
* none).
*/
public static Component an_awt_component()
{
/* just use the first component in the component list */
if (_all_awt_components.size() > 0)
return (Component)_all_awt_components.elementAt(0);
else
return null;
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Return some active AWT applet. Most code outside the toolkit itself
* should not need this.
*
* @return Applet an applet object which is currently hosting a
* subArctic interface (or null if there currently are none).
*/
public static Applet an_applet()
{
/* just use the first applet in the applet list */
if (_all_applets.size() > 0)
return (Applet)_all_applets.elementAt(0);
else
return null;
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Get a FontMetrics object for the given font.
* @param Font for_font the font we want the metrics object for.
* @return FontMetrics the metrics object for that font.
*/
public static FontMetrics get_metrics(Font for_font)
{
/* get it from the AWT native toolkit object */
return default_toolkit().getFontMetrics(for_font);
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* An image that we provide when a requested image can't be loaded or
* otherwise has a problem. This will be statically initialized in memory
* so it will always be there.
*/
protected static Image _broken = null;
/**
* A loaded_image that we provide when a requested image can't be loaded or
* otherwise has a problem. This will be statically initialized in memory
* so it will always be there.
*/
protected static loaded_image _broken_image_icon = null;
/**
* Provide a standard "broken image" icon that can be used to substitute
* for images that couldn't be loaded for some reason or another.
* This gets built from static data on first use.
*/
public static loaded_image broken_image_icon()
{
/* if we haven't done this before, build the image "manually" */
if (_broken_image_icon == null)
{
_broken = build_broken_icon();
/* create the loaded_image object */
_broken_image_icon = new loaded_image(_broken);
}
return _broken_image_icon;
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* This is the media id counter.
*/
static int media_counter=0;
/**
* This is the media tracker for use with the manager. Note that
* there can and WILL be concurrent access to the media tracker
* and to the counter. You better be sure you know what you
* are doing before you dink with this.
*/
static private MediaTracker tracker;
/**
* This object is a lock for the manager's media tracker.
* We can't lock the media tracker itself, because it
* can't be created at class load time. Thus we need something
* to lock on to insure that the tracker is ok, including
* in the case where it is not yet created.
*/
static private Integer media_lock=new Integer(0); // who cares
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Block until the given image is loaded (or there is an error in loading).
* Returns false if there was an error in loading.
*
* @param Image img the image to wait for
* @return boolean true if everything went ok
*/
public static boolean wait_for_image(Image img)
{
int ct=0; // this is a copy of the t
MediaTracker track;
/* first we want to make sure that we can get things initialized
ok... we are going to do a "test and set" so that we are
sure that we got the media tracker initialized and that
we updated the counter inside the lock
*/
synchronized (media_lock) {
if (tracker==null) {
tracker=new MediaTracker(an_awt_component());
}
track=tracker;
ct=media_counter++;
}
// synchronized (img) {
//track=new MediaTracker(an_awt_component());
track.addImage(img, ct);
try {
track.waitForID(ct);
} catch(InterruptedException ex) { }
// }
/* determine and return status */
return !track.isErrorID(ct);
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Load an image from the given URL. If or there is an error in loading,
* the broken image icon is returned instead.
*
* @param URL from_url the location to load the image from.
* @return loaded_image the resulting image (or the broken image if there was
* a problem).
*/
public static loaded_image load_image(URL from_url)
{
Object fetch_result;
/* URL.getContent is is broken in Netscape (at least at v2.01). It
* seems to throw an IOException for pretty much any image you try to
* load. Consequently, here we try to load using an stashed applet
* first (that works in Netscape). Only if we don't have an applet
* (probably never) do we do it the right way. The use of the applet
* here should go away should Netscape ever get fixed.
*/
// this should get put under workaround support
/* if we have an applet to work with load the image with that */
Applet an_ap = an_applet();
if (an_ap != null)
{
fetch_result = an_ap.getImage(from_url);
}
else
{
try {
/* get whatever is out there */
fetch_result = from_url.getContent();
} catch (IOException ex) {
return broken_image_icon();
}
}
/* see if we got an image. note: there is no standard about what gets
* returned from getContent(), so we have to handle several
* possibilities. */
if (fetch_result instanceof ImageProducer)
{
return new loaded_image(
default_toolkit().createImage((ImageProducer)fetch_result));
}
else if (fetch_result instanceof Image)
{
return new loaded_image((Image)fetch_result);
}
else
{
return broken_image_icon();
}
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Load an image from a location named relative to the document that
* contains the given applet. If or there is an error in loading, the
* broken image icon is returned instead.
*
* @param Applet host_ap the applet that is within the page we are
* fetching relative to.
* @param String image_file_name the name of the image file.
* @param loaded_image the resulting image (or the broken image if there was
* a problem).
*/
public static loaded_image load_doc_image(
Applet host_ap,
String image_file_name) throws MalformedURLException
{
URL doc_base, image_url;
/* get the base URL for the loaded document */
doc_base = host_ap.getDocumentBase();
/* append the file name */
image_url = new URL(doc_base, image_file_name);
/* try to load the image */
return load_image(image_url);
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Load an image from a location named relative to the location of the
* code (the .class file) for the given applet. If or there is an error
* in loading, the broken image icon is returned instead.
*
* @param Applet host_ap the applet whose code we are fetching
* relative to.
* @param String image_file_name the name of the image file.
* @param loaded_image the resulting image (or the broken image if there was
* a problem).
*/
public static loaded_image load_code_image(
Applet host_ap,
String image_file_name)
throws MalformedURLException
{
URL code_base, image_url;
/* get the base URL for the loaded document */
code_base = host_ap.getCodeBase();
/* append the file name */
image_url = new URL(code_base, image_file_name);
/* try to load the image */
return load_image(image_url);
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Debugging routine to print a trace of the current call stack on
* on the given PrintStream, then return.
*
* @param PrintStream strm where we print the call stack trace.
*/
public static void print_stack_trace(PrintStream strm)
{
/* throw and immediately catch an exception to get the trace */
try {
throw new sub_arctic_error();
} catch (stack_trace ex) { ex.printStackTrace(strm); }
// not clear we have to actually throw the exception, but...
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Debugging routine to print a trace of the current call stack on
* on System.err, then return.
*/
public static void print_stack_trace()
{
/* throw and immediately catch an exception to get the trace */
try {
throw new sub_arctic_error();
} catch (stack_trace ex) { ex.printStackTrace(System.err); }
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Option flag to handle an unexpected exception by printing a stack trace
* on System.error and then exiting. This is the default.
*/
public static final int EXCEPTION_STACK_CRASH = 0;
/**
* Option flag to handle an unexpected exception by printing a stack trace
* on System.error and then continuing.
*/
public static final int EXCEPTION_PRINT_STACK = 1;
/**
*Option flag to handle an unexpected exception by printing the exception
* message to System.err and then exiting.
*/
public static final int EXCEPTION_MESSAGE_CRASH = 2;
/**
* Option flag to handle an unexpected exception by printing the exception
* message to System.err and then continuing.
*/
public static final int EXCEPTION_PRINT_MESSAGE = 3;
/**
* Option flag to handle an unexpected exception by sending the
* "handle_exception()" message to the object previously registered
* via "handle_exceptions_with()". This this object was never registered,
* or is null, then the default of printing a stack trace and exiting is
* used as a fallback.
*/
public static final int EXCEPTION_CUSTOM = 4;
/**
* Option flag to ignore unexpected exceptions -- this is generally a very
* bad idea, think twice before using this.
*/
public static final int EXCEPTION_IGNORE = 5;
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* The current exception handling response. This must be one of the
* EXCEPTION_* option values.
*/
protected static int _handling_mechanism = EXCEPTION_STACK_CRASH;
/**
* The current exception handling response. This will be one of the
* EXCEPTION_* option values.
*/
public static int handling_mechanism() {return _handling_mechanism;}
/**
* The current custom exception handling object (if any). When exception
* handling is being done via EXCEPTION_CUSTOM, this object is passed
* exceptions to handle.
*/
protected static exception_handler _handle_object = null;
/**
* The current custom exception handling object (if any). When exception
* handling is being done via EXCEPTION_CUSTOM, this object is passed
* exceptions to handle.
*/
public static exception_handler handle_object() {return _handle_object;}
/**
* Establish how unexpected exceptions are handled. The handling_type
* parameter indicates one of several possible responses (see the
* EXCEPTION_* constants). The handler parameter indicates an object that
* will handle the exception if EXCEPTION_CUSTOM is used (it can passed is
* null otherwise).
*
* @param int handling_type code indicating how to handle an
* unexpected exception.
* @param exception_handler handler the handler object that gets the
* exception if handling_type is
* EXCEPTION_CUSTOM.
*/
public static void handle_exceptions_with(
int handling_type, exception_handler handler)
{
_handling_mechanism = handling_type;
_handle_object = handler;
}
/** Establish how unexpected exceptions are handled. The handling_type
* parameter indicates one of several possible standard responses (see the
* EXCEPTION_* constants).
*
* @param int handling_type code indicating how to handle an
* unexpected exception.
*/
public static void handle_exceptions_with(int handling_type)
{
handle_exceptions_with(handling_type, null);
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Handle an unexpected exception that arrived at some part of the toolkit.
* The specific action undertaken is controlled by the last call to
* handle_exceptions_with().
*
* @see #handle_exceptions_with()
* @param Exception except the unexpected exception.
*/
public static void handle_unexpected_exception(Exception except)
{
/* Do what we've been told to do */
switch (_handling_mechanism)
{
default:
case EXCEPTION_STACK_CRASH:
except.printStackTrace(System.err);
System.exit(1);
break;
case EXCEPTION_PRINT_STACK:
except.printStackTrace(System.err);
break;
case EXCEPTION_MESSAGE_CRASH:
System.err.println(except.getMessage());
System.exit(1);
break;
case EXCEPTION_PRINT_MESSAGE:
System.err.println(except.getMessage());
break;
case EXCEPTION_CUSTOM:
if (_handle_object != null)
_handle_object.handle_exception(except);
else
{
except.printStackTrace(System.err);
System.exit(1);
}
break;
case EXCEPTION_IGNORE:
/* do nothing... */
break;
}
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
// cycle handling needs its own set of constants...
/**
* The current constraint cycle handling response. This should have
* one of the EXCEPTION_* values that designate a response to an
* unexpected exception. Default is to ignore the cycle.
*/
protected static int _cycle_handling_mechanism = EXCEPTION_IGNORE;
/**
* The current constraint cycle handling response. This should have
* one of the EXCEPTION_* values that designate a response to an
* unexpected exception. Default is to ignore the cycle.
*/
public static int cycle_handling_mechanism() {return _handling_mechanism;}
/**
* The current custom constraint handling handling object (if any). When
* cycle handling is being done via EXCEPTION_CUSTOM, this object is passed
* cycles to handle.
*/
protected static cycle_handler _cycle_handle_object = null;
/**
* The current custom exception handling object (if any). When
* cycle handling is being done via EXCEPTION_CUSTOM, this object is passed
* cycles to handle.
*/
public static cycle_handler cycle_handle_object()
{return _cycle_handle_object;}
/**
* Establish how constraint cycles are handled. The handling_type
* parameter indicates one of several possible responses (see the
* EXCEPTION_* constants). The handler parameter indicates an object that
* will handle the cycle if EXCEPTION_CUSTOM is used (it can be passed as
* null otherwise).
*
* @param int handling_type the code indicating how to handle the
* cycle.
* @param cycle_handler handler the optional handler object used when
* handling_type is EXCEPTION_CUSTOM.
*/
public static void handle_cycles_with(
int handling_type, cycle_handler handler)
{
_cycle_handling_mechanism = handling_type;
_cycle_handle_object = handler;
}
/**
* Establish how constraint cycles are handled. The handling_type
* parameter indicates one of several possible standard responses (see the
* EXCEPTION_* constants).
*
* @param int handling_type the code indicating how to handle the
* cycle.
*/
public static void handle_cycles_with(int handling_type)
{
handle_cycles_with(handling_type, null);
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Handle a cycle. If normal processing at the point of the cycle
* is to proceed, true is returned. Otherwise, the caller of this routine
* should leave the current value in the attribute marked up-to-date (this
* only happens with custom handlers).
*
* @param interactor in_obj the interactor in which the cycle was first
* detected.
* @param int part_code the part within that object where the cycle was
* first detected.
*/
public static boolean handle_cycle(interactor in_obj, int part_code)
{
/* Do what we've been told to do */
switch (_cycle_handling_mechanism)
{
default:
case EXCEPTION_STACK_CRASH:
System.err.println("Cycle detected in " + in_obj.tag_str() +
" (part_code=" + part_code + ")");
print_stack_trace();
System.exit(1);
break;
case EXCEPTION_PRINT_STACK:
System.err.println("Cycle detected in " + in_obj.tag_str() +
" (part_code=" + part_code + ")");
print_stack_trace();
break;
case EXCEPTION_MESSAGE_CRASH:
System.err.println("Cycle detected in " + in_obj.tag_str() +
" (part_code=" + part_code + ")");
System.exit(1);
break;
case EXCEPTION_PRINT_MESSAGE:
System.err.println("Cycle detected in " + in_obj.tag_str() +
" (part_code=" + part_code + ")");
break;
case EXCEPTION_CUSTOM:
if (_cycle_handle_object != null)
return _cycle_handle_object.handle_cycle(in_obj, part_code);
else
{
print_stack_trace();
System.exit(1);
}
break;
case EXCEPTION_IGNORE:
/* do nothing... */
break;
}
/* unless the custom handler returned something we just proceed with
* evaluation */
return true;
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Establish an associative link between the given part of a value_consumer
* (usually an interactor) and part of a value_provider (usually an
* external_constraint) that gives it a value. (This is part of the
* "external" or "heavyweight" constraint system.)
*
* @param value_consumer cons_obj the object being constrained.
* @param int cons_part the part within that object being
* constrained.
* @param value_provider prov_obj the object (often a constraint) providing
* the value.
* @param int prov_part the part of that object that provides the
* value.
*/
public static void establish_extern_constraint(
value_consumer cons_obj,
int cons_part,
value_provider prov_obj,
int prov_part)
{
consumer_part_ref key = new consumer_part_ref(cons_obj, cons_part);
provider_part_ref entry = new provider_part_ref(prov_obj, prov_part);
/* put the provider part in the table under the consumer part */
_extern_constraints_table.put(key,entry);
/* tell tell the provider its attached */
prov_obj.attach_dependent(prov_part, cons_obj, cons_part);
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Remove any association between the given part of a value_consumer and
* a value_producer. (This is part of the "external" or "heavyweight"
* constraint system.)
*
* @param value_consumer cons_obj the object that was being constrained.
* @param int cons_part the part within that object that was being
* constrained.
* @param value_provider prov_obj the object (often a constraint) that was
* providing the value.
* @param int prov_part the part of that object that was providing
* the value.
*/
public static void drop_extern_constraint(
value_consumer cons_obj,
int cons_part)
{
provider_part_ref entry;
consumer_part_ref key = new consumer_part_ref(cons_obj, cons_part);
/* take it out of the table */
entry = (provider_part_ref)_extern_constraints_table.remove(key);
/* let it know that its been detached */
if (entry != null && entry.obj != null)
entry.obj.detach_dependent(entry.part_num, cons_obj, cons_part);
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Get the value_provider and part associated with the given value_consumer
* part. Returns null if no such association has been stored. (This is part
* of the "external" or "heavyweight" constraint system.)
*
* @param value_consumer cons_obj the consumer object we determining the
* provider (typically constraint) for.
* @param int cons_part the part of that object we are asking
* about.
* @return provider_part_ref a reference to the object and part providing the
* inquired about value, or null if there is none.
*/
public static provider_part_ref find_extern_constraint(
value_consumer cons_obj,
int cons_part)
{
consumer_part_ref key = new consumer_part_ref(cons_obj, cons_part);
/* look it up in the table */
return (provider_part_ref)_extern_constraints_table.get(key);
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Add an element to the notify list being maintained for the given
* value_provider part. This list represents the set of things that need
* to be informed when the provider part changes value (or might have changed
* value).
*
* @param value_provider for_prov the object (providing a value) which
* needs to inform others of changes.
* @param int for_part the part of that object we are concerned
* with.
* @param value_consumer notify_obj the object we are to notify.
* @param int notify_part the part of that object we are to notify.
*/
public static void add_to_ood_notify(
value_provider for_prov,
int for_part,
value_consumer notify_obj,
int notify_part)
{
Vector notify_list;
provider_part_ref key = new provider_part_ref(for_prov, for_part);
consumer_part_ref entry = new consumer_part_ref(notify_obj, notify_part);
/* get the list entry for our provider */
notify_list = (Vector)_notify_list_table.get(key);
/* if we don't have a list, make one and put it in the table */
if (notify_list == null)
{
notify_list = new Vector(1);
_notify_list_table.put(key,notify_list);
}
/* add to the end of the list */
notify_list.addElement(entry);
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Remove an element from the notify list being maintained for the given
* value_provider part. Return true if the list is then empty.
*
* @param value_provider for_prov the object (providing a value) which
* had been notifying.
* @param int for_part the part of that object we are concerned
* with.
* @param value_consumer notify_obj the object we were to notify.
* @param int notify_part the part of that object we were to
* notify.
*/
public static boolean remove_ood_notify(
value_provider for_prov,
int for_part,
value_consumer notify_obj,
int notify_part)
{
Vector notify_list;
provider_part_ref key = new provider_part_ref(for_prov, for_part);
consumer_part_ref entry = new consumer_part_ref(notify_obj, notify_part);
/* get the list entry for our provider */
notify_list = (Vector)_notify_list_table.get(key);
/* if we don't have a list, we are done */
if (notify_list == null) return true;
/* otherwise remove the element in question */
notify_list.removeElement(entry);
return notify_list.isEmpty();
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Get the notify list being maintained for the given value_provider part.
* Returns null if no list items has been stored for the provider.
*
* @param value_provider for_prov the object we are asking about.
* @param int for_part the part of that object whose notify list
* we want.
* @return Vector a vector of consumer_part_ref objects that the given
* object/part is to notify should it change (or null if no
* notify list has been stored for that object).
*/
public static Vector get_ood_notify(value_provider for_prov, int for_part)
{
provider_part_ref key = new provider_part_ref(for_prov, for_part);
return (Vector)_notify_list_table.get(key);
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Build the "broken image" icon from static data.
* @return Image the broken image icon.
*/
protected static Image build_broken_icon()
{
int w = 33;
int h = 32;
int data[] = new int[w*h];
/* compose the RGB pixels for the gray value */
for (int i=0; i<w*h; i++)
data[i] = (255 << 24) | (broken_icon_data[i] << 16) |
(broken_icon_data[i] << 8) | broken_icon_data[i];
/* build a memory image source and turn that into an image */
return default_toolkit().createImage(
new MemoryImageSource(w,h, data, 0, w));
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Data for icon representing a "broken" image. This is a 33x32 icon. The
* data is 0..255 grayscale.
*/
static int[] broken_icon_data = {
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,226,255,255,
255,209,209,209,209,209,209,209,209,209,209,209,214,223,255,229,229,
229,229,229,229,229,229,229,229,229,229,229,229,225,209,255,255,229,
255,229,229,229,229,229,229,229,229,229,229, 61,236,204,179,179,179,
179,179,179,179,179,179,179,179,179,179,179, 93,209,255,255,229,179,
131,131,131,131,131,131,131,131,131, 78,122,242,131,131,131,131,131,
131,131,131,131,131,131,131,131,131,131, 65,209,255,255,229,179,131,
131,131,131,131,131,131,131,131,139,176,215, 81, 89,140,131,131,131,
131,131,131,131,131,131,131,131,131, 65,209,255,255,229,179,131,131,
131,131,131,131,131,115, 35, 81,200,255,209,206,167,125,142,142,131,
131,131,131,131,131,131,131,131, 65,209,255,255,229,179,131,131,131,
131,131,131,115, 1,192,255,255,255,255,255,239,255,151,193,156,131,
131,131,131,131,131,131,131, 65,209,255,255,229,179,131,131,131,131,
131,131, 26,195,255,255,142,106,142,204,159,162,255,236,198,134,131,
131,131,131,131,131,131, 65,209,255,255,229,179,131,131,131,131,131,
115, 61,255,255, 43,206,251,132,255,225,111,255,255,173,187,131,131,
131,131,131,131,131, 65,209,255,255,229,179,131,131,131,131,131, 82,
162,255,209,178,162, 56,143,242,131, 65,255,255,140,239,131,131,131,
131,131,131,131, 65,209,255,255,229,179,131,131,131,131,131, 84,203,
255,131,236, 87, 73,255,131,131, 29,255,255,128,255,131,131,131,131,
131,131,131, 65,209,255,255,229,179,131,131,131,131,131,140,125, 71,
89,244,101,208,209,131, 62, 98,255,255, 64,236,131,131,131,131,131,
131,131, 65,209,255,255,229,179,131,131,131,131,131,132,190,229,217,
143,125,178,228, 64, 59,255,255,198,132,176,131,131,131,131,131,131,
131, 65,209,255,255,229,179,131,131,131,131,131,131,131,131,131,131,
131,140,229,112,255,255,226, 73,255,131,131,131,131,131,131,131,131,
65,209,255,255,229,179,131,131,131,131,131,131,131,131,131,131, 95,
43,255,255,255,226, 70,223, 57, 95,143,126,142,131,131,131,131, 65,
209,255,255,208,145,128,150,154,131,131,131,109, 92, 87,158, 17,240,
255,255,234, 17,123, 87,220,251,255,200,167,158,139,131,131, 65,214,
255,255,255,255,255,211,153,150,100, 17,120,225,250,197,206,255,255,
255, 96,142,255,192,131,131,140,211,215,226,159,148,103,122,255,255,
255,179,131,132,206,215,209,203,251,242,192,183,176,255,255,255,255,
255,222,131,131,131,131,131,131,158,222,255,255,237,222,255,255,255,
179,131,131,131,184,229,229,142,131,131,131, 40,255,255,255,129,247,
131,131,131,131,131,131,131,131,131,131,131,139,212,255,255,255,179,
131,131,131,131,131,131,131,131,131,131, 81,255,255,242, 84,233,131,
131,131,131,131,131,131,131,131,131,131, 61,156,255,255,255,179,131,
131,131,131,131,131,131,131,131,131,120,189,217,183,228,181,131,131,
131,131,131,131,131,131,131,131,131, 61,156,255,255,255,179,131,131,
131,131,131,131,131,131,131,131, 59,147,222, 86,154,147,131,131,131,
131,131,131,131,131,131,131,131, 61,156,255,255,255,179,131,131,131,
131,131,131,131,131,131,131, 31,255,255,255,245,179,131,131,131,131,
131,131,131,131,131,131,131, 61,156,255,255,255,179,131,131,131,131,
131,131,131,131,131,131, 31,255,255,255,222,179,131,131,131,131,131,
131,131,131,131,131,131, 61,156,255,255,255,179,131,131,131,131,131,
131,131,131,131,131,131,217,184,253, 75,204,131,131,131,131,131,131,
131,131,131,131,131, 61,156,255,255,255,179,131,131,131,131,131,131,
131,131,131,131,134,165,150,255,226,159,131,131,131,131,131,131,131,
131,131,131,131, 61,156,255,255,255,179,131,131,131,131,131,131,131,
131,131,131,131,131,118,255,131,131,131,131,131,131,131,131,131,131,
131,131,131, 61,156,255,255,255,179,131,131,131,131,131,131,131,131,
131,131,131,131, 87,255,131,131,131,131,131,131,131,131,131,131,131,
131,131, 61,156,255,255,255,179,131,131,131,131,131,131,131,131,131,
131,131, 79,161,242,131,131,131,131,131,131,131,131,131,131,131,131,
131, 61,156,255,255,255,179,131,131,131,131,131,131,131,131,131,131,
131, 61,255,147,111,111,111,111,111,111,111,111,111,111,111,111,111,
46,159,255,255,255,126, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
107,255, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 84,
179,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255 };
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* This holds the system's default color pair
*/
protected static color_pair _default_color_pair=null;
/**
* This function returns the default color pair for the system.<p>
*
* <b>Note</b>: This is now obsolete -- use the style system instead.
*
* @return color_pair the system's default color pair
*/
public static color_pair default_color_pair() {
if (_default_color_pair==null) {
color_scheme cs=style_manager.default_color_scheme();
_default_color_pair=new color_pair(cs.foreground(),
cs.base());
}
return _default_color_pair;
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Private counter for allocating unique positive integer values (we
* ignore the fact that this will eventually wrap-around, so if you need
* one every micro-second, do it yourself with a long).
*/
private static int _unique_int = 0;
/**
* Return a positive integer value that is unique among results from this
* routine (we ignore the fact that this will eventually wrap-around, so
* if you need one every micro-second, do it yourself with a long).
*/
public static int unique_int() {return _unique_int++; }
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/* STUFF FOR THE WORK AGENT AND MULTITHREADING */
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* You can call this method from another thread and it will perform
* the work represented by the work_proc with the system in a safe
* synchronization state.
*
* @param work_proc wp an object representing what code to run with the
* system in a safe state (its really a closure, in
* some sense).
* @param Object arg the argument to pass to the work_proc when the
* system reaches a safe state.
*/
static public void perform_work(work_proc wp, Object arg) {
/* create the pair to hold the two objects */
work_pair pair=new work_pair(wp,arg);
/* get a component to send the event to */
Component c=an_awt_component();
/* make the awt event */
Event evt=new Event(an_awt_component(),work_agent.WORK_EVENT,
pair);
/* post that event */
c.postEvent(evt);
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/* Work around identification infrastructure */
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/* Platform identifiers and associated workaround ids. Each platform is
* limited to 32 workarounds (1<<0 .. 1<<31). If you run out of space for
* ids under a given platform, just start a new one. When you add
* a new platform be sure to fix WA_MAX_PLATFORM_ID as well.
*/
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Special platform id to support dynamically added workarounds. This
* allows people to temporarily put in a platform specific fix even
* if they can't modify identify_platform_workarounds(). In general,
* these id's should be avoided in favor of an "official" id. Note:
* there are only 32 workaround id's available under this "platform"
* and its up to you to avoid conflicts.
*/
public static int WA_DYNAMIC = 0;
public static int WA_USER1 = 1<<0; public static int WA_USER2 = 1<<1;
public static int WA_USER3 = 1<<2; public static int WA_USER4 = 1<<3;
public static int WA_USER5 = 1<<4; public static int WA_USER6 = 1<<5;
public static int WA_USER7 = 1<<6; public static int WA_USER8 = 1<<7;
public static int WA_USER9 = 1<<8; public static int WA_USER10 = 1<<9;
public static int WA_USER11 = 1<<10; public static int WA_USER12 = 1<<11;
public static int WA_USER13 = 1<<12; public static int WA_USER14 = 1<<13;
public static int WA_USER15 = 1<<14; public static int WA_USER16 = 1<<15;
public static int WA_USER17 = 1<<16; public static int WA_USER18 = 1<<17;
public static int WA_USER19 = 1<<18; public static int WA_USER20 = 1<<19;
public static int WA_USER21 = 1<<20; public static int WA_USER22 = 1<<21;
public static int WA_USER23 = 1<<22; public static int WA_USER24 = 1<<23;
public static int WA_USER25 = 1<<24; public static int WA_USER26 = 1<<25;
public static int WA_USER27 = 1<<26; public static int WA_USER28 = 1<<27;
public static int WA_USER29 = 1<<28; public static int WA_USER30 = 1<<29;
public static int WA_USER31 = 1<<30; public static int WA_USER32 = 1<<31;
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/** Platform id for workarounds related to Netscape 3.x on all machines. */
public static int WA_NS3_ALL = 1;
/* no workarounds yet */
/** Platform id for workarounds related to Netscape 3.x on Suns */
public static int WA_NS3_SUN = 2;
/* no workarounds yet */
/** Platform id for workarounds related to Netscape 3.x on Wintel machines. */
public static int WA_NS3_PC = 3;
/* no workarounds yet */
/** Platform id for workarounds related to Netscape 3.x on the Mac */
public static int WA_NS3_MAC = 4;
public static int WA_TRACKER_HANGS = 1<<0;
public static int WA_REDUNDANT_MOVES = 1<<1;
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/** Platform id for workarounds related to JDK 1.0.x on all machines. */
public static int WA_JDK1_ALL = 5;
/* no workarounds yet */
/** Platform id for workarounds related to JDK 1.0.x on Sun machines.*/
public static int WA_JDK1_SUN = 6;
/* no workarounds yet */
/** Platform id for workarounds related to JDK 1.0.x on Wintel machines. */
public static int WA_JDK1_PC = 7;
/* no workarounds yet */
/** Platform id for workarounds related to JDK 1.0.x on the Mac.*/
public static int WA_JDK1_MAC = 8;
/* no workarounds yet */
/** Platform id for workarounds related to MS Internet Explorer 3.x. */
public static int WA_IE3 = 9;
/* no workarounds yet */
/** Largest platform id in use */
public static int WA_MAX_PLATFORM_ID = WA_IE3;
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Table of workaround sets. Workarounds are named by a pair of integers.
* The first integer is a platform id, the second is a workaround id
* associated with that platform. Each index in the table represents a
* particular platform (this is the platform that a particular bug or
* workaround was first identified on, it does not necessarily mean it
* is limited to that platform). The integer at each index represents
* a set of at most 32 different workarounds associated with that platform.
* This table is initialized at run-time by identify_platform_workarounds()
* (which is invoked early by a static initializer) based on some detective
* work to determine which platform we are actually running on.
*/
protected static int[] _workaround_table;
/* static init for the above table */
static {
identify_platform_workarounds();
};
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Helper routine to dump useful system properties to System.out. You can
* use this to determine at least part of the "signature" of a new platform
* that you need to incorporate into identify_platform_workarounds().
*/
public static void dump_platform_properties()
{
System.out.println("System Properties for this Platform Include:");
System.out.println("--------------------------------------------");
System.out.println("os.arch=\"" + System.getProperty("os.arch") + "\"");
System.out.println("os.name=\"" + System.getProperty("os.name") + "\"");
System.out.println("os.version=\"" +
System.getProperty("os.version") + "\"");
System.out.println("java.version=\"" +
System.getProperty("java.version") + "\"");
System.out.println("java.vendor=\"" +
System.getProperty("java.vendor") + "\"");
System.out.println("java.class.version=\"" +
System.getProperty("java.class.version") + "\"");
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Do the detective work to determine which platform we are on and hence
* which set of platform specific work arounds should be enabled. This
* will be called once by a static initializer here in the manager. It
* sets up the _workaround_table array used by need_workaround() to
* determine which platform specific workarounds are needed and which are
* not.<p>
*
* <b>Editorial Comment</b>:
* The need for this routine is a very clear indication that Java, and in
* particular AWT, has as of yet utterly and completely failed to deliver
* on the promise of "write once run everywhere".
*/
protected static void identify_platform_workarounds()
{
String os_name;
String os_arch;
String os_version;
String java_version;
String vendor;
String java_class_version;
/* start with an empty set of active workarounds */
_workaround_table = new int[WA_MAX_PLATFORM_ID];
for (int i = 0; i < WA_MAX_PLATFORM_ID; i++)
_workaround_table[i] = 0;
/* Get identifying properties */
os_name = System.getProperty("os.name");
os_arch = System.getProperty("os.arch");
os_version = System.getProperty("os.version");
java_version = System.getProperty("java.version");
vendor = System.getProperty("java.vendor");
java_class_version = System.getProperty("java.class.version");
/* do platform specific setup of _workaround_table */
/* -------- JDK --------*/
if (vendor.startsWith("Sun Microsystems"))
{
/* so far, no JDK workarounds... */
}
/* -------- Netscape --------*/
else if (vendor.startsWith("Netscape"))
{
/* look at java.version to decide between 2.x and 3.x */
if (java_version.equals("1.021"))
{
/* this is 2.02 -- don't know about earlier 2.x's yet*/
}
else if (java_version.equals("1.02"))
{
/* this is 3.0 -- separate out HW/SW platforms of interest */
/* Macintosh */
if (os_name.equals("Mac OS"))
{
_workaround_table[WA_NS3_MAC] |=
(WA_TRACKER_HANGS | WA_REDUNDANT_MOVES);
}
}
}
/* -------- need the other here... --------*/
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/**
* Determine if a given platform specific workaround (identified by a
* platform id and workaround id pair) is needed on the platform we are
* currently running on. Note: workarounds are not necessarily limited
* to the platform whose id they are associated with -- this is just the
* first platform for which the workaround was identified and helps
* segregate the workaround id name space and make it more extensible.<p>
*
* <b>Editorial Comment</b>:
* The need for this routine is a very clear indication that Java, and in
* particular AWT, has as of yet utterly and completely failed to deliver
* on the promise of "write once run everywhere".
*
* @param int platform_id First part of identification of a particular
* workaround (this identifies the platform that the
* workaround was first associated with).
*
* @param int workaround_id Second part of identification of a particular
* workaround (this uniquely identifies it within
* the group associated with a platform).
* @return boolean indicating whether the given workaround is needed on the
* platform we are currently running on.
*
*/
public static boolean need_workaround(int platform_id, int workaround_id)
{
return (_workaround_table[platform_id] & workaround_id) != 0;
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/** Activate a specific platform specific workaround. This is here to allow
* activation of known workarounds on the basis of new circumstances (or
* circumstances that can only be determined dynamically). This can also
* be used with the WA_DYNAMIC platform id for indicating temporary platform
* specific fixes without updating identify_platform_workarounds().
* (Such usage should be only temporary, however, because there are only
* 32 such workaround id's available and no conflict resolution scheme is
* provided.)<p>
*
* @param int platform_id First part of identification of the particular
* workaround to the activated (this identifies the
* platform that the workaround was first associated
* with).
*
* @param int workaround_id Second part of identification of the particular
* workaround to be activated (this uniquely
* identifies it within the group associated with a
* platform).
*/
public static void activate_workaround(int platform_id, int workaround_id)
{
/* make sure we are in range */
if (platform_id > WA_MAX_PLATFORM_ID) return;
_workaround_table[platform_id] |= workaround_id;
}
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
}
/*=========================== COPYRIGHT NOTICE ===========================
This file is part of the subArctic user interface toolkit.
Copyright (c) 1996 Scott Hudson and Ian Smith
All rights reserved.
The subArctic system is freely available for most uses under the terms
and conditions described in
http://www.cc.gatech.edu/gvu/ui/sub_arctic/sub_arctic/doc/usage.html
and appearing in full in the lib/interactor.java source file.
The current release and additional information about this software can be
found starting at: http://www.cc.gatech.edu/gvu/ui/sub_arctic/
========================================================================*/