/**************************************************************************
* Parts copyright (c) 2001, 2002, 2003 by Punch Telematix. All rights *
* reserved. *
* Parts copyright (c) 2004 by Chris Gray, /k/ Embedded Java Solutions. *
* All rights reserved. *
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* 1. Redistributions of source code must retain the above copyright *
* notice, this list of conditions and the following disclaimer. *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* 3. Neither the name of Punch Telematix or of /k/ Embedded Java Solutions*
* nor the names of other contributors may be used to endorse or promote*
* products derived from this software without specific prior written *
* permission. *
* *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED *
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. *
* IN NO EVENT SHALL PUNCH TELEMATIX, /K/ EMBEDDED JAVA SOLUTIONS OR OTHER *
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
**************************************************************************/
package java.awt;
import java.util.*;
import java.awt.dnd.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.peer.*;
import java.awt.Color;
import com.acunia.wonka.rudolph.FocusControl;
import com.acunia.wonka.rudolph.FocusControlFactory;
import com.acunia.wonka.rudolph.FocusCycle;
/**
** The parent class of all AWT components.
*/
public abstract class Component implements java.awt.image.ImageObserver, MenuContainer, java.io.Serializable {
// Tree lock:
static private final Object lock;
// Counter
static private int counter;
static {
lock = new Object();
}
// Default font on which we can fall-back:
public static final Font DEFAULT_FONT = new Font("helvP08", Font.PLAIN, 8);
// (text) alignment definitions
public static final float BOTTOM_ALIGNMENT = 1.0f;
public static final float CENTER_ALIGNMENT = 0.5f;
public static final float LEFT_ALIGNMENT = 0.0f;
public static final float RIGHT_ALIGNMENT = 1.0f;
public static final float TOP_ALIGNMENT = 0.0f;
// Component dimensions:
int x;
int y;
int height;
int width;
// Sizes:
Dimension prefSize;
Dimension minSize;
Dimension maximumSize;
boolean isPacked;
// Name:
String name;
boolean nameExplicitlySet;
// Visibility:
boolean visible = true;
// Validation:
boolean valid = false;
transient boolean validate = false;
// Enabled:
boolean enabled = true;
// Notification:
transient protected boolean notified = false;
//Locale:
Locale locale;
// Parent container:
transient Container parent = null;
// Background and foreground color:
Color background;
Color foreground;
// Cursor
transient Cursor cursor;
// Events:
transient ComponentListener componentListener;
transient MouseMotionListener mouseMotionListener;
transient MouseListener mouseListener;
transient FocusListener focusListener;
transient ActionListener actionListener;
transient KeyListener keyListener;
boolean newEventsOnly;
transient boolean eventsEnabled = true;
// Font:
Font font;
Font peerFont;
// protected ComponentPeer peer;
transient public ComponentPeer peer;
Vector popups;
/*
** Focus :
**
** These fields are updated from Event_addFocusEvent (Event.c)
** and are used by the taskbar to revert the focus to the
** original Component that had focus..
** The next 2 methods are used to revert focus and to get
** the Component which currently has focus.
*/
transient private static Component focusComponent = null;
transient private static Component focusComponentPrev = null;
boolean hasFocus;
private FocusControl focusControl = FocusControlFactory.create();
private DropTarget dropTarget;
public static void revertFocus() {
FocusCycle.prev(focusComponent);
}
public static Component getFocusComponent() {
return focusComponent;
}
protected Component() {
counter++;
name = "Component" + counter;
if(focusComponent==null) {
focusComponent = this;
}
addNotify();
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return (name != null) ? name : "";
}
public void setForeground(Color color) {
synchronized(getTreeLock()) {
this.foreground = color;
peer.setForeground(color);
}
}
public Color getForeground() {
if (this.foreground != null) return this.foreground;
return (parent != null) ? parent.getForeground() : null;
}
public void setBackground(Color color) {
background = color;
peer.setBackground(color);
}
public Color getBackground() {
if (this.background != null) return this.background;
return (parent != null) ? parent.getBackground() : null;
}
public java.awt.image.ColorModel getColorModel() {
return peer.getColorModel();
}
public synchronized void setFont(Font font) {
synchronized(getTreeLock()) {
this.font = font;
valid = false;
peer.setFont(font);
}
}
public Font getFont() {
if (this.font != null) {
return this.font;
}
else if (parent != null) {
return parent.getFont();
}
else {
return DEFAULT_FONT;
}
}
public FontMetrics getFontMetrics(Font font) {
return peer.getFontMetrics((font == null) ? Component.DEFAULT_FONT : font);
}
public synchronized void setCursor(Cursor cursor) {
this.cursor = cursor;
peer.setCursor(cursor);
}
public Cursor getCursor() {
return cursor;
}
public void setBounds(int x, int y, int width, int height) {
synchronized (getTreeLock()) {
boolean l = (this.x != x || this.y != y) ? true : false;
boolean s = (this.width != width || this.height != height) ? true : false;
if (l || s) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
// Invalidate the component:
invalidate();
if (componentListener != null) {
if (s) {
dispatchEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_RESIZED));
}
if (l) {
dispatchEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_MOVED));
}
}
peer.setBounds(x, y, width, height);
}
}
}
public void setBounds(Rectangle rectangle) {
setBounds(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
}
public Rectangle getBounds() {
return new Rectangle(x, y, width, height);
}
public void setSize(int w, int h) {
setBounds(this.x, this.y, w, h);
}
public void setSize(Dimension dimension) {
setBounds(this.x, this.y, dimension.width, dimension.height);
}
public Dimension getSize() {
return new Dimension(width, height);
}
/*
** Depricated methods.
*/
public Dimension size() {
return new Dimension(width, height);
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getHeight() {
return height;
}
public int getWidth() {
return width;
}
public ComponentPeer getPeer() {
return peer;
}
public boolean contains(int x, int y) {
return (x < width && y < height);
}
public boolean contains(Point point) {
return contains(point.x, point.y);
}
public Dimension getMinimumSize() {
return minimumSize();
}
public Dimension getPreferredSize() {
return preferredSize();
}
public Dimension getMaximumSize() {
return maximumSize();
}
public Dimension minimumSize() {
synchronized (getTreeLock()) {
if (minSize == null || valid == false) {
minSize = peer.getMinimumSize();
}
return minSize;
}
}
public Dimension preferredSize() {
synchronized (getTreeLock()) {
if (prefSize == null || valid == false) {
prefSize = peer.getPreferredSize();
}
return prefSize;
}
}
public Dimension maximumSize() {
return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
}
public void setLocation(int x, int y) {
setBounds(x, y, this.width, this.height);
}
public void setLocation(Point point) {
setBounds(point.x, point.y, this.width, this.height);
}
public Point getLocation() {
synchronized (getTreeLock()) {
return new Point(x, y);
}
}
public Point getLocationOnScreen() {
synchronized (getTreeLock()) {
return peer.getLocationOnScreen();
}
}
public Component getComponentAt(int x, int y) {
return (contains(x, y) ? this : null);
}
public Component getComponentAt(Point point) {
return (contains(point.x, point.y) ? this : null);
}
public void list(java.io.PrintStream out, int indent) {
}
public void list(java.io.PrintWriter out, int indent) {
}
public void list() {
list(System.out,0);
}
public void list(java.io.PrintStream out) {
list(out,0);
}
public void list(java.io.PrintWriter out) {
list(out,0);
}
public Container getParent() {
return parent;
}
public void doLayout() {
}
public float getAlignmentX() {
return CENTER_ALIGNMENT;
}
public float getAlignmentY() {
return CENTER_ALIGNMENT;
}
public void addNotify() {
if (notified == false) {
notified = true;
}
if (peer == null) {
peer = getToolkit().createComponent(this);
}
}
public void removeNotify() {
}
public synchronized void add(PopupMenu popup) {
/*
** TODO: Do something useful. For now just ignore this since we don't need it..
*/
}
public synchronized void remove(MenuComponent popup) {
/*
** TODO: Do something useful. For now just ignore this since we don't need it..
*/
}
public final Object getTreeLock() {
return lock;
}
public void setLocale(java.util.Locale locale){
this.locale = locale;
}
public java.util.Locale getLocale() throws IllegalComponentStateException{
if (locale != null) {
return locale;
}
if (parent != null) {
return parent.getLocale();
}
throw new IllegalComponentStateException("no locale set for this component or its parents");
}
public void requestFocus() {
if (focusComponent != this) {
if(this.peer!=null) {
this.peer.requestFocus();
}
focusComponentPrev = focusComponent;
focusComponent = this;
if (focusComponentPrev != null) {
focusComponentPrev.dispatchEvent
(new FocusEvent(focusComponentPrev, FocusEvent.FOCUS_LOST));
}
dispatchEvent(new FocusEvent(focusComponent, FocusEvent.FOCUS_GAINED));
}
}
public void transferFocus() {
FocusCycle.next(this);
}
/**
* @status not implemented
* @remark not compliant with specifications
*/
public boolean isFocusTraversable() {
if(this.peer!=null)
{
return this.peer.isFocusTraversable();
}
else
{
return false;
}
}
public void validate() {
valid = true;
}
public void invalidate() {
synchronized(getTreeLock()) {
if (valid) {
minSize = null;
prefSize = null;
valid = false;
// if parent exists, invalidate parent component
if ((parent != null) && (parent.valid)) {
parent.invalidate();
}
}
}
}
public boolean isValid() {
return valid;
}
public void setEnabled(boolean condition) {
enabled = condition;
peer.setEnabled(condition);
}
public boolean isEnabled() {
return enabled;
}
public synchronized void addComponentListener(ComponentListener listener) {
componentListener = AWTEventMulticaster.add(componentListener, listener);
}
public synchronized void removeComponentListener(ComponentListener listener) {
componentListener = AWTEventMulticaster.remove(componentListener, listener);
}
public synchronized void addFocusListener(java.awt.event.FocusListener listener) {
focusListener = AWTEventMulticaster.add(focusListener, listener);
}
public synchronized void removeFocusListener(java.awt.event.FocusListener listener) {
focusListener = AWTEventMulticaster.remove(focusListener, listener);
}
public synchronized void addKeyListener(java.awt.event.KeyListener listener) {
keyListener = AWTEventMulticaster.add(keyListener, listener);
}
public synchronized void removeKeyListener(java.awt.event.KeyListener listener) {
keyListener = AWTEventMulticaster.remove(keyListener, listener);
}
public synchronized void addMouseListener(MouseListener listener) {
mouseListener = AWTEventMulticaster.add(mouseListener, listener);
}
public synchronized void removeMouseListener(MouseListener listener) {
mouseListener = AWTEventMulticaster.remove(mouseListener, listener);
}
public synchronized void addMouseMotionListener(MouseMotionListener listener) {
mouseMotionListener = AWTEventMulticaster.add(mouseMotionListener, listener);
}
public synchronized void removeMouseMotionListener(java.awt.event.MouseMotionListener listener) {
mouseMotionListener = AWTEventMulticaster.remove(mouseMotionListener, listener);
}
/**
* @status dummy implementation
* @remark not compliant with specifications: just prints a message
*/
protected final void enableEvents(long eventTypes) {
}
protected final void disableEvents(long eventTypes) {
}
protected void dispatchEventImpl(AWTEvent event) {
if (enabled == false && event instanceof InputEvent) {
// If a component is not enabled it can not generate events
// nor respond to events (or user input for that matter).
return;
}
peer.handleEvent((AWTEvent)event);
if(dropTarget != null && event instanceof MouseEvent){
com.acunia.wonka.rudolph.DropTargetEvent.setDropTargetContext(dropTarget.getDropTargetContext());
com.acunia.wonka.rudolph.DropTargetEvent.getDropTargetEvent().dispatch(((MouseEvent)event));
}
if(dropTarget == null && event instanceof MouseEvent && event.getID() == MouseEvent.MOUSE_RELEASED_AFTER_DRAG) {
com.acunia.wonka.rudolph.DropTargetEvent.setInProgress(false,null);
}
else {
processEvent(event);
}
}
public final void dispatchEvent(AWTEvent event) {
dispatchEventImpl(event);
}
protected void processEvent(AWTEvent event) {
if (event instanceof MouseEvent) {
switch(event.getID()) {
case MouseEvent.MOUSE_ENTERED:
case MouseEvent.MOUSE_EXITED:
case MouseEvent.MOUSE_PRESSED:
case MouseEvent.MOUSE_RELEASED:
case MouseEvent.MOUSE_CLICKED:
processMouseEvent((MouseEvent) event);
break;
case MouseEvent.MOUSE_MOVED:
case MouseEvent.MOUSE_DRAGGED:
processMouseMotionEvent((MouseEvent) event);
break;
}
}
else if (event instanceof KeyEvent) {
processKeyEvent((KeyEvent) event);
}
else if (event instanceof FocusEvent) {
processFocusEvent((FocusEvent) event);
}
else if (event instanceof ItemEvent) {
processEvent(event);
}
else if (event instanceof ComponentEvent) {
processComponentEvent((ComponentEvent) event);
}
}
protected void processComponentEvent(ComponentEvent event) {
if (componentListener != null) {
switch(event.getID()) {
case ComponentEvent.COMPONENT_RESIZED:
componentListener.componentResized(event);
break;
case ComponentEvent.COMPONENT_MOVED:
componentListener.componentMoved(event);
break;
case ComponentEvent.COMPONENT_SHOWN:
componentListener.componentShown(event);
break;
case ComponentEvent.COMPONENT_HIDDEN:
componentListener.componentHidden(event);
break;
}
}
}
protected void processFocusEvent(FocusEvent event) {
if (focusListener != null) {
switch(event.getID()) {
case FocusEvent.FOCUS_GAINED:
focusListener.focusGained(event);
break;
case FocusEvent.FOCUS_LOST:
focusListener.focusLost(event);
break;
}
}
}
protected void processKeyEvent(java.awt.event.KeyEvent event) {
if (keyListener != null) { // && (!event.isConsumed())) {
switch(event.getID()) {
case KeyEvent.KEY_TYPED:
keyListener.keyTyped(event);
break;
case KeyEvent.KEY_PRESSED:
keyListener.keyPressed(event);
break;
case KeyEvent.KEY_RELEASED:
keyListener.keyReleased(event);
break;
}
}
if(!event.isConsumed())
{
this.focusControl.processKeyEvent(event);
}
}
protected void processMouseEvent(MouseEvent event) {
if (mouseListener != null) {
switch(event.getID()) {
case MouseEvent.MOUSE_EXITED:
mouseListener.mouseExited(event);
break;
case MouseEvent.MOUSE_ENTERED:
mouseListener.mouseEntered(event);
break;
case MouseEvent.MOUSE_PRESSED:
mouseListener.mousePressed(event);
break;
case MouseEvent.MOUSE_RELEASED:
mouseListener.mouseReleased(event);
break;
case MouseEvent.MOUSE_CLICKED:
mouseListener.mouseClicked(event);
break;
}
}
}
protected void processMouseMotionEvent(java.awt.event.MouseEvent event) {
if (mouseMotionListener != null) {
switch(event.getID()) {
case MouseEvent.MOUSE_MOVED:
mouseMotionListener.mouseMoved(event);
break;
case MouseEvent.MOUSE_DRAGGED:
mouseMotionListener.mouseDragged(event);
break;
}
}
}
/**
* @status not implemented
* @remark not compliant with specifications
*/
public void print(Graphics context) {
throw new RuntimeException("Not implemented");
}
/**
* @status not implemented
* @remark not compliant with specifications
*/
public void printAll(Graphics context) {
throw new RuntimeException("Not implemented");
}
public String toString() {
String display = (name == null)? getClass().getName() : name;
return display +" - bounds: x = "+ x +", y = "+ y +", w = "+ width +", h = "+ height;
}
/**
* @status not implemented
* @remark not compliant with specifications
*/
protected String paramString() {
return getClass().getName() +"<"+name+"> - bounds("+ x +", "+ y +", "+ width +", "+ height+")";
}
public boolean isVisible() {
return visible;
}
public void setVisible(boolean condition) {
synchronized(getTreeLock()) {
if (condition) {
// Show component:
if (!visible) {
visible = true;
invalidate();
peer.setVisible(condition);
validate();
// Component listener:
if (componentListener != null) {
dispatchEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_SHOWN));
}
}
}
else {
// Hide component:
if (visible) {
visible = false;
peer.setVisible(condition);
invalidate();
// Component listener:
if (componentListener != null) {
dispatchEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_HIDDEN));
}
}
}
}
}
public void show() {
setVisible(true);
}
public void hide() {
setVisible(false);
}
public boolean isDisplayable() {
return (peer != null);
}
/**
* @status not implemented
* @remark not compliant with specifications
*/
public boolean isShowing() {
return isVisible();
}
/**
* @status implemented
* @remark not compliant with specifications: a Graphics object is
* always constructed and returned, even if the component
* is not visible or its peer component does not exist.
*/
public Graphics getGraphics() {
return peer.getGraphics();
}
public Toolkit getToolkit() {
return Toolkit.getDefaultToolkit();
}
public Image createImage(int w, int h) {
return peer.createImage(w, h);
}
public Image createImage(java.awt.image.ImageProducer producer) {
return peer.createImage(producer);
}
public boolean prepareImage(Image image, ImageObserver observer) {
return prepareImage(image, -1, -1, observer);
}
public boolean prepareImage(Image image, int w, int h, ImageObserver observer) {
return peer.prepareImage(image, w, h, observer);
}
public int checkImage(Image image, ImageObserver observer) {
return checkImage(image, -1, -1, observer);
}
public int checkImage(Image image, int w, int h, ImageObserver observer) {
return peer.checkImage(image, w, h, observer);
}
/*
** Called by Image.getWidth(ImageObserver) and getHeight(ImageObserver). Graphics.drawImage(..... ImageObserver)
** and Component prepareImage(ImageObserver) / CheckImage(ImageObserver) to send diagnostic data to the
** <this>-ImageObserver-interface Component.
** designed to be overridden by subclasses to get the diagnostics
** returns true = <yes, there are still more of these messages to come> unless the flags contain ImageObserver.ALLBITS
*/
public boolean imageUpdate(Image image, int flags, int x, int y, int w, int h) {
if((flags & ImageObserver.FRAMEBITS) != 0)
repaint();
return((flags & ImageObserver.ALLBITS) == 0);
}
public void repaint() {
peer.repaint(0, 0, 0, width, height);
}
public void repaint(long ms) {
peer.repaint(ms, 0, 0, width, height);
}
public void repaint(int x, int y, int w, int h) {
peer.repaint(0, x, y, w, h);
}
public void repaint(long ms, int x, int y, int w, int h) {
peer.repaint(ms, x, y, w, h);
}
public void paint(Graphics context) {
}
public void update(Graphics g) {
g.clearRect(0, 0, width, height);
paint(g);
}
public void paintAll(Graphics context) {
// Validate container
validate();
}
/* private void readObject(java.io.ObjectInputStream s) throws ClassNotFoundException, java.io.IOException {
System.out.println("Not yet implemented");
}
private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
System.out.println("Not yet implemented");
}*/
/*
** All the following methods are very very deprecated...
*/
public boolean action(Event evt, Object arg) {
System.out.println("Not implemented - Deprecated");
return false;
}
public Rectangle bounds() {
return getBounds();
}
public void deliverEvent(Event e) {
System.out.println("Not implemented - Deprecated");
}
public void disable() {
enabled = false;
peer.setEnabled(false);
}
public void enable() {
enabled = true;
peer.setEnabled(true);
}
public void enable(boolean cond) {
setEnabled(cond);
}
public boolean gotFocus(Event evt, Object arg) {
System.out.println("Not implemented - Deprecated");
return false;
}
public boolean handleEvent(Event evt) {
System.out.println("Not implemented - Deprecated");
return false;
}
public boolean inside(int x, int y) {
return contains(x, y);
}
public boolean keyDown(Event evt, int key) {
System.out.println("Not implemented - Deprecated");
return false;
}
public boolean keyUp(Event evt, int key) {
System.out.println("Not implemented - Deprecated");
return false;
}
public void layout() {
System.out.println("Not implemented - Deprecated");
}
public Component locate(int x, int y) {
return getComponentAt(x, y);
}
public Point location() {
return getLocation();
}
public boolean lostFocus(Event evt, Object arg) {
System.out.println("Not implemented - Deprecated");
return false;
}
public boolean mouseDown(Event evt, int x, int y) {
System.out.println("Not implemented - Deprecated");
return false;
}
public boolean mouseDrag(Event evt, int x, int y) {
System.out.println("Not implemented - Deprecated");
return false;
}
public boolean mouseEnter(Event evt, int x, int y) {
System.out.println("Not implemented - Deprecated");
return false;
}
public boolean mouseExit(Event evt, int x, int y) {
System.out.println("Not implemented - Deprecated");
return false;
}
public boolean mouseMove(Event evt, int x, int y) {
System.out.println("Not implemented - Deprecated");
return false;
}
public boolean mouseUp(Event evt, int x, int y) {
System.out.println("Not implemented - Deprecated");
return false;
}
public void move(int x, int y) {
setLocation(x, y);
}
public void nextFocus() {
transferFocus();
}
public void reshape(int x, int y, int w, int h) {
setBounds(x, y, w, h);
}
public void resize(int w, int h) {
setSize(w, h);
}
public void resize(Dimension d) {
setSize(d);
}
public void show(boolean cond) {
setVisible(cond);
}
/*
**methods 1.2
*/
public void setDropTarget(DropTarget dt){
dropTarget = dt;
}
public DropTarget getDropTarget(){
return dropTarget;
}
/**
** Called by EventQueue.postEvent() to see whether newEvent should be
** merged with oldEvent (which was found in the queue). oldEvent and
** newEvent are guaranteed to have the same source and ID. Returns
** null if no merging is possible, or a merged event with which
** postEvent() will overwrite oldEvent on the queue.
** <p>The default implementation currently does nothing; it would be
** a good idea to merge paint/repaint events here. User-defined
** components may override this.
*/
protected AWTEvent coalesceEvents(AWTEvent oldEvent, AWTEvent newEvent)
{
return null;
}
}