"Implementing
a Grid Layout Manager with Positionable Components,"
Volume: 3
Issue: 12, p. 56
Listing 1
/**
* Copyright (c) 1997 Daniel Dee
* Description:
Package contains common classes for the Vivigraphics
widget
Toolkit - a callback-based toolkit.
Originally, part of the Eva Toolkit - the prototype
implementation.
*/
package com.wigitek.vivigraphics.widget.gui;
import java.awt.Component;
import java.awt.Container;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Dimension;
import java.awt.LayoutManager;
import java.util.Hashtable;
import com.wigitek.vivigraphics.widget.common.*;
/**
* This class implements a layout with fixed-size grids. The
dimension
of the grids can be either specified or be constantly
adjusted
to be able to fully contain any of the components in the
layout.
PositionableGridLayout works with PositionableGridConstraints
to
determine how
to position a given Component within its Container.
* @version $Revision$
* @author Originally written by Daniel Dee, 2/21/96
* @see GridConstraints
*/
public class PositionableGridLayout extends Object implements
LayoutManager
{
/**
* Creates a PositionableGridLayout with a default grid width
and height.
Automatically adjusts size of grid to accomodate
the largest component.
*/
public PositionableGridLayout ()
{
this( _defaultGridWidth, _defaultGridHeight, new
Insets(2,2,2,2),
AUTO_ADJUST );
}
/**
* Creates a PositionableGridLayout with a specified grid width
and height.
* @param gridWidth the specified gridWidth
* @param gridHeight the specified gridHeight
* @param adjust specifies to auto-adjust to accomodate the
largest component
*/
public PositionableGridLayout( int gridWidth, int gridHeight,
Insets
insets, int adjust )
{
comptable = new
Hashtable();
// creates a
component-constraints hash table
defaultConstraints = new PositionableGridConstraints();
// creates a
default PositionableGridConstraints for components whose constraints
are
not specified
this.gridWidth = gridWidth + insets.left +
insets.right;
this.gridHeight = gridHeight + insets.top +
insets.bottom;
this.insets = insets;
this.adjust = adjust;
}
/**
* Sets the constraints for the specified component.
* @param comp the component to be modified
* @param constraints the constraints to be applied
*/
public void setConstraints(Component comp,
PositionableGridConstraints
constraints)
{
comptable.put(comp, constraints.clone());
}
/**
* Retrieves the constraints for the specified component.
A copy of
the constraints is returned.
* @param comp the component to be queried
*/
public PositionableGridConstraints getConstraints(Component
comp)
{
PositionableGridConstraints constraints =
(PositionableGridConstraints)comptable.get(comp);
// If constraints have not been set for the specified
component,
// return a copy of the default one.
if (constraints == null)
{
setConstraints(comp,
defaultConstraints);
constraints =
(PositionableGridConstraints)comptable.get(comp);
}
return
(PositionableGridConstraints)constraints.clone();
}
/**
* Retrieves the constraints for the specified component.
The return
value is not a copy, but is the actual constraints
class used by the
layout mechanism.
* @param comp the component to be queried
*/
public PositionableGridConstraints lookupConstraints(Component
comp)
{
PositionableGridConstraints constraints =
(PositionableGridConstraints)comptable.get(comp);
// If constraints have not been set for the
specified component,
// return a copy of the default one.
if (constraints == null) {
setConstraints(comp,
defaultConstraints);
constraints =
(PositionableGridConstraints)comptable.get(comp);
}
return constraints;
}
/**
* Returns the pixel coordinate identified by the grid
location x and y.
* @param gridx the grid x location
* @param gridy the grid y location
* @returns the pixel position
*/
public Point coordinates(int gridx, int gridy)
{
Point loc = new Point(0,0);
if (layoutInfo == null)
return loc;
loc.x = layoutInfo.startx + gridx * gridWidth;
loc.y = layoutInfo.starty + gridy * gridHeight;
return loc;
}
/**
* Returns the grid position identified by the pixel
coordinates x and y.
* @param x the pixel x coordinate
* @param y the pixel y coordinate
* @returns the grid position
*/
public Point getLocation(int x, int y)
{
Point loc = new Point(0,0);
int i, d;
if (layoutInfo == null)
return loc;
// Find the row position by scanning from the
starting
// pixel position of the layout, and counting the
number
// of gridWidth increments required to get the
pixel
// coordinate x. The number of increments is the grid
x
// position.
d = layoutInfo.startx;
for (i=0; i<layoutInfo.width; i++)
{
d += gridWidth;
if (d > x)
break;
}
loc.x = i;
// Find the column position by scanning from the
starting
// pixel position of the layout, and counting the
number
// of gridHeight increments required to get the
pixel
// coordinate y. The number of increments is the grid
y
// position.
d = layoutInfo.starty;
for (i=0; i<layoutInfo.height; i++) {
d += gridHeight;
if (d > y)
break;
}
loc.y = i;
return loc;
}
public Component getComponent(Container parent, int gridx, int
gridy)
{
Component comp;
int compindex;
PositionableGridConstraints constraints;
Component components[] = parent.getComponents();
/*
* If the parent has no slaves anymore, then don't
do anything
* at all: just leave the parent's size
as-is.
*/
if (components.length == 0)
return null;
/*
* Now do the actual layout using the layout
information
* that has been collected.
*/
for (compindex = 0 ; compindex < components.length ;
compindex++)
{
comp = components[compindex];
constraints = lookupConstraints(comp);
if( constraints.gridx == gridx &&
constraints.gridy == gridy )
return comp;
}
return
null;
}
/**
* Adds the specified component with the specified name to the
layout.
Does not apply.
* @param name the name of the component
* @param comp the component to be added
*/
public void addLayoutComponent(String name, Component comp)
{
}
/**
* Removes the specified component from the layout. Does not
apply.
* @param comp the component to be removed
*/
public void removeLayoutComponent(Component comp)
{
}
/**
* Returns the preferred dimensions for this layout given the
components
in the specified panel.
* @param parent the component which needs to be laid out
* @see #minimumLayoutSize
*/
public Dimension preferredLayoutSize(Container parent)
{
return minimumLayoutSize(parent);
}
/**
* Returns the minimum dimensions needed to layout the
components
contained in the specified panel.
* @param parent the component which needs to be laid out
* @see #preferredLayoutSize
*/
public Dimension minimumLayoutSize(Container parent)
{
PositionableGridLayoutInfo layoutInfo =
GetGridLayoutInfo(parent);
Dimension d = new Dimension();
Insets parentInsets = parent.getInsets();
d.width = layoutInfo.width * gridWidth +
parentInsets.left +
parentInsets.right;
d.height = layoutInfo.height * gridHeight +
parentInsets.top +
parentInsets.bottom;
return d;
}
/**
* Lays out the container in the specified panel.
* @param parent the specified component being laid out
* @see Container
*/
public void layoutContainer(Container parent)
{
Component comp;
int compindex;
PositionableGridConstraints constraints;
Component components[] = parent.getComponents();
Point p;
PositionableGridLayoutInfo info;
/*
* If the parent has no slaves anymore, then don't
do anything
* at all: just leave the parent's size
as-is.
*/
if (components.length == 0)
return;
/*
* Start by getting basic layout information.
*/
info = GetGridLayoutInfo(parent);
layoutInfo = info;
/*
* Now do the actual layout using the layout
information
* that has been collected.
*/
for (compindex = 0 ; compindex <
components.length ; compindex++)
{
comp = components[compindex];
if (!comp.isVisible())
continue;
constraints = lookupConstraints(comp);
p = coordinates( constraints.gridx,
constraints.gridy );
// Reshape the component according the
constraints associated with it.
// Then set the grid dimension in the
component's constraints to the
actual value.
constraints = lookupConstraints(comp);
if( constraints.gridwidth == 0 ||
constraints.gridheight == 0 )
{
Dimension compPreferredSize =
comp.getPreferredSize();
constraints.gridwidth =
constraints.gridwidth ==
PositionableGridConstraints.PREFERRED_SIZE ?
compPreferredSize.width :
constraints.gridwidth;
constraints.gridheight =
constraints.gridheight ==
PositionableGridConstraints.PREFERRED_SIZE ?
compPreferredSize.height :
constraints.gridheight;
}
// Adjust the component's position based
on its specified anchor point
//p = AdjustForGravity(constraints, p,
constraints.gridwidth,
constraints.gridheight );
Dimension compDimension =
comp.getSize();
Point compLocation =
comp.getLocation();
if( compLocation.x != p.x || compLocation.y
!= p.y ||
compDimension.width
!= constraints.gridwidth ||
compDimension.height
!= constraints.gridheight )
{
// If not fill the
entire grid...
/*if(
constraints.gridwidth !=
PositionableGridConstraints.FILL_SIZE &&
constraints.gridheight !=
PositionableGridConstraints.FILL_SIZE )
else*/
{
int w = constraints.gridwidth !=
PositionableGridConstraints.FILL_SIZE ? compDimension.width :
gridWidth;
int h = constraints.gridheight !=
PositionableGridConstraints.FILL_SIZE ? compDimension.height :
gridHeight;
comp.setBounds(p.x, p.y, w,
h);
}
}
}
}
/*
* Fill in an instance of the PositionableGridLayoutInfo
structure for
the current set
* of managed children.
*/
protected PositionableGridLayoutInfo GetGridLayoutInfo(Container
parent)
{
PositionableGridLayoutInfo r = new
PositionableGridLayoutInfo();
PositionableGridConstraints constraints;
Dimension d;
Insets parentInsets = parent.getInsets();
Component comp, components[] =
parent.getComponents();
int compindex;
int curX, curY, curRow, curCol;
// Adjust startx and starty to include the parent's
insets.
r.startx = parentInsets.left;
r.starty = parentInsets.top;
// Figure out the dimensions of the layout
grid.
// Start with zero grid dimensions.
r.width = r.height = 0;
// If automatic adjustment is desired, find the
largest component
// in width and height.
//if( adjust == AUTO_ADJUST )
// Now find the components furthest right and
furthest down.
curRow = curCol = -1;
for (compindex = 0 ; compindex <
components.length ; compindex++)
{
comp = components[compindex];
if (!comp.isVisible())
continue;
constraints = lookupConstraints(comp);
curX = constraints.gridx;
curY = constraints.gridy;
// If x or y is negative, then use
relative positioning.
if (curX < 0 )
curX = curCol >= 0 ? curCol +
1 : 0;
if (curY < 0)
curY = curRow >= 0 ? curRow +
1 : 0;
// Adjust the layout's cell width and
height to include the
// new component if necessary.
if( r.width < curX + 1 ) r.width = curX +
1;
if( r.height < curY + 1 ) r.height = curY
+ 1;
// Save x and y coordinate of this
component in case the
// next component added is position RELATIVE
to this one.
curRow = curX;
curCol = curY;
}
return r;
}
private static final int _defaultGridWidth = 30; //
default grid
dimension in a new layout
private static final int _defaultGridHeight = 30;
private int
gridWidth;
// actual grid
dimension in a layout
private int gridHeight;
private Insets
insets;
// insets around grid
cells
private int
adjust;
// specifies if
auto-adjust
protected static final int MAXGRIDSIZE = 128;
protected Hashtable comptable;
protected PositionableGridConstraints defaultConstraints;
protected PositionableGridLayoutInfo layoutInfo;
public static final int AUTO_ADJUST = 0;
public static final int NO_ADJUST = 1;
public static final int HORIZONTAL = 2;
public static final int VERTICAL = 3;
}
class PositionableGridLayoutInfo
{
int width, height;
/* number of
cells horizontally, vertically */
int startx, starty;
/* starting
point for layout in pixel
coordinates */
}
Listing 2
/**
* Copyright (c) 1997 Daniel Dee
* Description:
Package contains common classes for the Vivigraphics
widget
Toolkit - a callback-based toolkit.
Originally, part of the Eva Toolkit - the prototype
implementation.
*/
package com.wigitek.vivigraphics.widget.common;
/**
* This class encapsulates the instance variables that tell a
GridLayout how to position a given Component within its
Container.
This class also implements Cloneable.
* Note: The GridLayout class supported by this class is a
completely
different implementation of the AWT version. GridConstraints
will
not work with java.awt.GridLayout.
* @version $Revision$
* @author Originally written by Daniel Dee, 2/21/96
* @author Last updated by $Author$, $Date$
* @see GridLayout
*/
public class PositionableGridConstraints extends Object implements
Cloneable
{
/**
* Constructs a PositionableGridConstraints specifying
RELATIVE
positioning and
selecting PREFERRED_SIZE as the values for
gridx, gridy, gridwidth and gridheight.
*/
public PositionableGridConstraints ()
{
this( RELATIVE, RELATIVE, PREFERRED_SIZE, PREFERRED_SIZE
);
}
/**
* Constructs a GridConstraints CENTERed on the specified grid
position and
selecting PREFERRED_SIZE as the values for
gridwidth and gridheight.
* @param gridx the x position in a GridLayout
* @param gridy the y position in a GridLayout
*/
public PositionableGridConstraints ( int gridx, int gridy )
{
this( gridx, gridy, PREFERRED_SIZE, PREFERRED_SIZE,
CENTER );
}
/**
* Constructs a GridConstraints with specified grid position at
the
specified anchor, and selecting PREFERRED_SIZE as
the values for
gridwidth
and gridheight.
* @param gridx the x position in a GridLayout
* @param gridy the y position in a GridLayout
* @param anchor the specified anchor
*/
public PositionableGridConstraints ( int gridx, int gridy, int
anchor )
{
this( gridx, gridy, PREFERRED_SIZE, PREFERRED_SIZE,
anchor );
}
/**
* Constructs a GridConstraints with specified grid position
and
dimension and
CENTERed anchor.
*/
public PositionableGridConstraints( int gridx, int gridy, int
gridwidth,
int gridheight )
{
this( gridx, gridy, gridwidth, gridheight, CENTER
);
}
/**
* Constructs a GridConstraints with specified grid position
and
dimension and anchor.
*/
public PositionableGridConstraints( int gridx, int gridy, int
gridwidth,
int gridheight, int anchor )
{
this.gridx = gridx;
this.gridy = gridy;
this.gridwidth = gridwidth;
this.gridheight = gridheight;
this.anchor = anchor;
}
/**
* Implements the clone() method required by the Cloneable
interface.
*/
public Object clone ()
{
try
{
PositionableGridConstraints c =
(PositionableGridConstraints)super.clone();
return c;
}
catch (CloneNotSupportedException e)
{
// this shouldn't happen, since we are
Cloneable
throw new InternalError();
}
}
public int gridx,
gridy; // grid
position of a component in a
GridLayout
public int gridwidth, gridheight; // dimension of a component
in a
GridLayout
public int
anchor;
// determines gravity of the component
in a
// GridLayout
public static final int RELATIVE = -1;
// specifies a position to
the right
// or below the previous component
public static final int PREFERRED_SIZE = 0; // specifies the use of
a
component's
// preferred size
public static final int FILL_SIZE = -1; //
specifies the use of grid
size as
// the component's size
public static final int CENTER = 10; // centers
component in grid
public static final int NORTH = 11; //
position component towards top
and center
public static final int NORTHEAST = 12; // position component
towards top
and right
public static final int EAST = 13; //
position component towards
center and right
public static final int SOUTHEAST = 14; // position component
towards
bottom and right
public static final int SOUTH = 15; //
position component towards
bottom and center
public static final int SOUTHWEST = 16; // position component
towards
bottom and left
public static final int WEST = 17; //
position component towards
center and left
public static final int NORTHWEST = 18; // position component
towards top
and left
}
Listing 3
/**
* Copyright (c) 1998 Daniel Dee
* Description:
Puzzle game. Objective is to shift tiles around until
you
arrange them in numerical order. Click on the tile to shift,
and
the empty space to shift it to. A tile can be shifted only
if
a space is adjacent to it.
*/
import java.applet.Applet;
import java.awt.Event;
import java.awt.Frame;
import java.awt.CardLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.Point;
import com.wigitek.vivigraphics.widget.common.*;
import com.wigitek.vivigraphics.widget.gui.*;
/**
* This class extends the java.awt.Button class to support
the callback mechanism by implementing the Widget
interface.
* @version $Revision$
* @author Originally written by Daniel Dee, 6/4/98
* @author Last updated by $Author$, $Date$
*/
public class Puzzle extends Applet
{
private Panel
panel;
private
PositionableGridLayout layout;
public void
init()
{
panel = new
Panel();
layout = new
PositionableGridLayout();
panel.addCallback( Panel.ACTIVATE_CALLBACK,
new PuzzleCallbackable(null,layout,panel,this) );
panel.setLayout( layout );
createPuzzle(this,panel,layout);
CardLayout
clayout = new CardLayout();
setLayout(
clayout );
add(
"Puzzle", panel );
}
public void
destroy()
{
panel =
null;
}
/**
* Create the
Puzzle.
* @param c the
Container for this Puzzle
* @param l the
PositionableGridLayout manager for this Puzzle
*/
private static
void createPuzzle( Container f, Container c,
PositionableGridLayout l )
{
PositionableGridConstraints constraints =
new PositionableGridConstraints();
constraints.gridwidth = constraints.gridheight =
PositionableGridConstraints.FILL_SIZE;
// Create 8
tiles in order.
for( int i=0;
i < 3; i++ )
for( int j=0;
j < 2 || (j == 2 && i != 2); j++ )
{
constraints.gridx = j;
constraints.gridy = i;
Button button
= new Button(
new Integer(i*3+(j+1)).toString() );
button.addCallback( Button.ACTIVATE_CALLBACK,
new PuzzleCallbackable(button,l,c,f) );
l.setConstraints( button, constraints );
c.add( button
);
}
}
/**
* This is the
main program to test the
PositionableGridLayout/Constraints class.
* @param args
unused
*/
public static
void main( String args[] )
{
Frame applic = new Frame(
"Eva Puzzle" );
Panel panel = new
Panel();
PositionableGridLayout layout = new PositionableGridLayout();
panel.addCallback( Panel.ACTIVATE_CALLBACK,
new PuzzleCallbackable(null,layout,panel,applic) );
panel.setLayout( layout );
Puzzle.createPuzzle(applic,panel,layout);
CardLayout
clayout = new CardLayout();
applic.setLayout( clayout );
applic.add(
"Puzzle", panel );
Dimension d =
layout.minimumLayoutSize(panel);
applic.setSize(d.width,d.height);
applic.setVisible(true);
Insets i =
applic.getInsets();
applic.setSize(d.width+i.left+i.right,d.height+i.top+i.bottom);
applic.setVisible(true);
}
}
/**
* Extension of Callbackable class to handle tile selection. If an
empty
space is selected, that means the previously selected tile
should be
moved to the empty location. Does nothing if that is not
possible, i.e.,
the empty space is not adjacent to the previously selected
tile.
*/
class PuzzleCallbackable extends Callbackable
{
/**
* Constructs a
PuzzleCallbackable.
* @param b the
button for which this Callback is created
* @param i the
PositionableGridLayout for this Puzzle's Container
* @param f the
Container for this Puzzle
*/
public
PuzzleCallbackable( Button b, PositionableGridLayout l,
Container f, Container c )
{
this.b =
b;
this.l =
l;
this.f =
f;
this.c =
c;
}
/**
* Activates this
Callbackable.
* @param e the
event that triggers this callback
*/
public boolean
activate( Event e )
{
if( b == null
) // an empty space is selected, probably a
tile move
{
if( selected != null ) // a tile was selected for
moving
{
// Check if tile move is valid
PositionableGridConstraints c
=
l.lookupConstraints(selected);
Point p = l.getLocation( e.x, e.y
);
if( (c.gridx == p.x+1 || c.gridx ==
p.x-1) &&
c.gridy == p.y )
c.gridx =
p.x;
else if((c.gridy == p.y+1 ||
c.gridy == p.y-1) && c.gridx ==
p.x)
c.gridy =
p.y;
f.doLayout();
f.repaint();
}
}
else // a
selection
selected = b;
return
true;
}
private Container c,
f;
private
PositionableGridLayout l;
private Button
b;
private static
Button selected;
}
Listing 4
/**
* Copyright (c) 1997 Daniel Dee
* Description:
Package contains common classes for the ViviGraphics
Widget
Toolkit - a callback-based toolkit.
Originally, part of the Eva Toolkit - the prototype
implementation.
*/
package com.wigitek.vivigraphics.widget.gui;
//import java.awt.Event;
import com.wigitek.vivigraphics.widget.gui.*;
import com.wigitek.vivigraphics.widget.common.*;
/**
* This class extends the java.awt.Button class to support
the callback mechanism by implementing the Widget
interface.
* @version $Revision$
* @author Originally written by Daniel Dee, 3/18/97
* @author Last updated by $Author$, $Date$
* @see Widget
*/
public class Panel extends java.awt.Panel implements Widget
{
/**
* Constructs an "unnamed" Panel.
*/
public Panel()
{
this( "unnamed"
);
}
/**
* Constructs a new Panel with given name.
* @param name the specified name
*/
public Panel( String name )
{
super();
this.name = name;
addMouseListener(activateCallbackList);
}
/**
* Registers a callback for the Panel. Panel
currently
recognizes RESIZE_CALLBACK.
Unknown
callback names are ignored.
* @param callbackName the type of callback to
register
* @param callback the
object of the Callbackable class that will
activated
when trigger by the callback type given by
callbackName
* @param clientData the object of the
ClientData class through which
the registering
object wants to pass data when the callback is
triggered.
* @see Callbackable
* @see ClientData
*/
public void addCallback( String callbackName,
Callbackable callback )
{
//if(
callbackName.compareTo(RESIZE_CALLBACK) == 0 )
//
resizeCallbackList.add( callback );
if(
callbackName.compareTo(ACTIVATE_CALLBACK) == 0 )
activateCallbackList.add( callback );
}
/**
* Sets the new size of this Panel widget.
* Note: this is specifically written to support
Eva.ScrollPane
* for JDK 1.0. It calls the resizeCallback.
* @param width the width
* @param height the height
*/
/*static private int prevW = 0, prevH = 0;
public void setSize(int width, int height)
{
if( width != prevW || height !=
prevH )
{
prevW =
width;
prevH =
height;
Event
evt = new Event(this,-1,null);
resizeCallbackList.activate(evt);
}
super.setSize(width,height);
}*/
/**
* Gets the name of the button.
Implements getName() method of the
Widget interface.
*/
public String getName()
{
return name;
}
/**
* Returns a String that represents the value of
this Object.
Overrides the method in
java.lang.Object.
* @return a String
* @see Object
*/
public String toString()
{
String string =
super.toString();
int length =
string.length();
return string.substring( 0,
length-1 ) + ",name=" + name + "]";
}
/**
* This is the main program to test the Panel
class.
* @param args unused
*/
/*public static void main( String args[] )
{
TopLevelFrame toplevel = new
TopLevelFrame( "Eva Toolkit: Panel
Test" );
toplevel.addCallback(
TopLevelFrame.DESTROY_CALLBACK, new
_TestCallbackable(), new ClientData() );
Panel panel = new Panel();
toplevel.add(panel);
toplevel.setSize(350,200);
toplevel.setVisible(true);
}*/
// The name of an instance of this class
private String name;
// Callbacks for scrollbar decrement.
//private CallbackList resizeCallbackList = new
CallbackList();
//public static final String RESIZE_CALLBACK =
"resizeCallback";
private CallbackList activateCallbackList = new
CallbackList();
public static final String ACTIVATE_CALLBACK =
"activateCallback";
Listing 5
/**
* Copyright (c) 1997 Daniel Dee
* Description:
Package contains common classes for the Vivigraphics
Widget
Toolkit - a callback-based callback-based toolkit.
Originally, part of the Eva Toolkit - the prototype
implementation.
*/
package com.wigitek.vivigraphics.widget.gui;
import java.awt.Event;
import java.awt.AWTEvent;
import java.util.Vector;
import java.io.IOException;
import java.awt.event.*;
import com.wigitek.vivigraphics.widget.common.Callbackable;
/**
* This class chains callbacks associated with a single callback
type
together.
* @version $Revision: 2.1 $
* @author Originally written by Daniel Dee, 3/17/97
* @author Last updated by $Author: daniel $, $Date: 1998/05/27
23:06:41 $
*/
public class CallbackList extends Vector
implements ActionListener,
AdjustmentListener,
ComponentListener,
ContainerListener,
FocusListener,
ItemListener,
KeyListener,
MouseListener,
MouseMotionListener,
TextListener,
WindowListener
{
/**
* Constructs a CallbackList. Creates a Vector with
100 initial elements
and a increment size of 100.
*/
public CallbackList()
{
super(100, 100);
}
/**
* This method is called when an action event
occurs inside the
source object. The corresponding
callbacks added
by the user are activated.
* @param evt the event
*/
public void actionPerformed(ActionEvent evt)
{
Event e = new Event(
evt.getSource(), evt.getID(), evt );
activate(e);
}
/**
* This method is called when an itemStateChanged
event occurs inside
this Component. However, Java AWT does
not seem to be able
to detect disarm condition, and hence,
unable to determine
itemStateChanged correctly. The
corresponding callbacks added
by the user are activated.
* @param evt the event
*/
public void itemStateChanged(ItemEvent evt)
{
Event e = new Event(
evt.getSource(), evt.getID(), evt );
if( evt.getStateChange() ==
ItemEvent.SELECTED )
activate(e);
}
/**
* This method is called when a keyDown event
occurs inside this
TextArea. It allows preprocessing of
input before display.
* @param evt the event
*/
public void keyPressed(KeyEvent evt)
{
int keychar;
int keycode =
(int)evt.getKeyCode();
switch(keycode)
{
case
KeyEvent.VK_UP:
keychar = Event.UP;
break;
case
KeyEvent.VK_DOWN:
keychar = Event.DOWN;
break;
default:
keychar = (int)evt.getKeyChar();
break;
}
Event e = new Event(
evt.getSource(), evt.getWhen(), evt.getID(),
0, 0, keychar, 0 );
activate(e);
evt.setKeyChar( (char)e.key
);
evt.setKeyCode( e.key );
}
public void textValueChanged(TextEvent evt)
{
Event e = new Event(
evt.getSource(), evt.getID(), evt );
activate(e);
}
public void mouseClicked(MouseEvent evt)
{
Event e = new Event(
evt.getSource(), evt.getWhen(), evt.getID(),
evt.getX(), evt.getY(), 0, 0 );
activate(e);
}
public void windowClosing(WindowEvent evt)
{
}
// TO BE
IMPLEMENTED
public void adjustmentValueChanged(AdjustmentEvent evt)
{}
public void componentResized(ComponentEvent evt)
{}
public void componentMoved(ComponentEvent evt) {}
public void componentShown(ComponentEvent evt) {}
public void componentHidden(ComponentEvent evt) {}
public void componentAdded(ContainerEvent evt) {}
public void componentRemoved(ContainerEvent evt)
{}
public void focusGained(FocusEvent evt) {}
public void focusLost(FocusEvent evt) {}
public void keyTyped(KeyEvent evt) {}
public void keyReleased(KeyEvent evt) {}
public void mousePressed(MouseEvent evt) {}
public void mouseReleased(MouseEvent evt) {}
public void mouseEntered(MouseEvent evt) {}
public void mouseExited(MouseEvent evt) {}
public void mouseDragged(MouseEvent evt) {}
public void mouseMoved(MouseEvent evt) {}
public void windowOpened(WindowEvent evt) {}
public void windowClosed(WindowEvent evt) {}
public void windowIconified(WindowEvent evt) {}
public void windowDeiconified(WindowEvent evt) {}
public void windowActivated(WindowEvent evt) {}
public void windowDeactivated(WindowEvent evt)
{}
/**
* Removes a Callbackable from the
CallbackList.
* @param cb the callback
*/
public boolean remove( Callbackable cb )
{
boolean returnValue =
false;
for( int i=0; i < size(); i++
)
{
Callbackable _cb = (Callbackable)elementAt(i);
if( _cb
== cb )
{
removeElementAt(i);
returnValue = true;
}
}
return returnValue;
}
/**
* Removes a CallbackClientPair at the indexed
position.
* @param index the position of the
CallbackClientPair in the
CallbackList.
*/
public boolean removeAt( int index )
{
try
{
removeElementAt( index );
return
true;
}
catch(
ArrayIndexOutOfBoundsException e )
{
return
false;
}
}
/**
* Adds a callback to a chain.
* @param callback the
callback
* @return the Callbackable
*/
public Callbackable add( Callbackable cb )
{
if( cb == null )
cb =
defaultCB;
addElement( cb );
return cb;
}
/**
* Calls all the callbacks in this chain.
* @param evt the event that triggers this
callbacklist
* @return true if event has been processed by the
callback
and no further processing is necessary; false
if further processing from the activating object
is required.
*/
public boolean activate( Event e )
{
boolean returnValue =
true;
for( int i=0; i < size(); i++
)
{
Callbackable cb = (Callbackable)elementAt(i);
returnValue = cb.activate( e );
}
return returnValue;
}
private CallbackListDefaultCallbackable defaultCB
=
new
CallbackListDefaultCallbackable();
}
/**
* Default Callbackable.
*/
class CallbackListDefaultCallbackable extends Callbackable
{
/**
* Prints information about the activating
object.
* @param
evt the event that triggers this
callback
*/
public boolean activate( Event evt )
{
System.out.println(
"Calling object is " + evt.target.toString() +
"." );
System.out.println(
"Activating event is " + evt.toString() + "." );
return true;
}
}