| /* Copyright (C) 1999, 2000 Free Software Foundation |
| |
| This file is part of libgcj. |
| |
| This software is copyrighted work licensed under the terms of the |
| Libgcj License. Please consult the file "LIBGCJ_LICENSE" for |
| details. */ |
| |
| package java.awt; |
| import java.awt.event.*; |
| import java.awt.image.*; |
| import java.io.PrintStream; |
| import java.io.PrintWriter; |
| import java.lang.reflect.*; |
| import java.util.EventListener; |
| import java.util.Locale; |
| import java.util.ResourceBundle; |
| import java.util.Vector; |
| import java.awt.peer.ComponentPeer; |
| import java.awt.peer.LightweightPeer; |
| import java.beans.PropertyChangeSupport; |
| import java.beans.PropertyChangeListener; |
| // import javax.accessibility.AccessibleContext; |
| |
| /** |
| * The root of all evil. |
| * |
| * Status: Incomplete. The event dispatch mechanism is implemented. All |
| * other methods defined in the J2SE 1.3 API javadoc exist, but are mostly |
| * incomplete or only stubs; except for methods relating to the Drag and Drop, |
| * Input Method, and Accessibility frameworks: These methods are present but |
| * commented out. |
| */ |
| public abstract class Component implements ImageObserver, MenuContainer, |
| java.io.Serializable |
| { |
| |
| /* Constants for use with getAlignmentX()/getAlignmentY(). */ |
| public static final float BOTTOM_ALIGNMENT = 1.0f, |
| CENTER_ALIGNMENT = 0.5f, |
| LEFT_ALIGNMENT = 0.0f, |
| RIGHT_ALIGNMENT = 1.0f, |
| TOP_ALIGNMENT = 0.0f; |
| |
| /* Make the treelock a String so that it can easily be identified |
| in debug dumps. We clone the String in order to avoid a conflict in |
| the unlikely event that some other package uses exactly the same string |
| as a lock object. */ |
| static Object treeLock = new String("AWT_TREE_LOCK"); |
| |
| /* Serialized fields from the serialization spec. */ |
| // FIXME: Default values? |
| int x; |
| int y; |
| int width; |
| int height; |
| Color foreground; |
| Color background; |
| Font font; |
| Font peerFont; |
| Cursor cursor; |
| Locale locale; |
| boolean visible = true; // default (except for Window) |
| boolean enabled = true; |
| boolean valid; |
| boolean hasFocus; |
| //DropTarget dropTarget; |
| Vector popups; |
| String name; |
| boolean nameExplicitlySet; |
| Dimension minSize; |
| Dimension prefSize; |
| boolean newEventsOnly; |
| long eventMask = AWTEvent.PAINT_EVENT_MASK; |
| PropertyChangeSupport changeSupport; |
| boolean isPacked; |
| int componentSerializedDataVersion; |
| /* AccessibleContext accessibleContext; */ |
| |
| /* Anything else is non-serializable, and should be declared "transient". */ |
| transient Container parent; |
| transient java.awt.peer.ComponentPeer peer; |
| |
| transient ComponentListener componentListener; |
| transient FocusListener focusListener; |
| transient KeyListener keyListener; |
| transient MouseListener mouseListener; |
| transient MouseMotionListener mouseMotionListener; |
| transient InputMethodListener inputMethodListener; |
| transient HierarchyListener hierarchyListener; |
| transient HierarchyBoundsListener hierarchyBoundsListener; |
| |
| transient ComponentOrientation orientation = ComponentOrientation.UNKNOWN; |
| |
| protected Component() |
| { |
| } |
| |
| public String getName() |
| { |
| if (name == null && !nameExplicitlySet) |
| name = generateName(); |
| return name; |
| } |
| |
| public void setName(String name) |
| { |
| nameExplicitlySet = true; |
| this.name = name; |
| } |
| |
| /** Subclasses should override this to return unique component names like |
| * "menuitem0". |
| */ |
| String generateName() |
| { |
| // Component is abstract. |
| return null; |
| } |
| |
| public Container getParent() |
| { |
| return parent; |
| } |
| |
| /** @deprecated */ |
| // However, Classpath's Gtk peers rely on it. |
| public java.awt.peer.ComponentPeer getPeer() |
| { |
| return peer; |
| } |
| |
| // FIXME: java.awt.dnd classes not yet implemented |
| /* |
| public void setDropTarget(DropTarget dt) |
| { |
| this.dropTarget = dt; |
| } |
| |
| public DropTarget getDropTarget() |
| { |
| return dropTarget; |
| } |
| */ |
| |
| /** @since 1.3 */ |
| public GraphicsConfiguration getGraphicsConfiguration() |
| { |
| return getGraphicsConfigurationImpl(); |
| } |
| |
| /** Implementation method that allows classes such as Canvas and |
| Window to override the graphics configuration without violating |
| the published API. */ |
| GraphicsConfiguration getGraphicsConfigurationImpl() |
| { |
| if (peer != null) |
| { |
| GraphicsConfiguration config = peer.getGraphicsConfiguration(); |
| if (config != null) |
| return config; |
| } |
| |
| if (parent != null) |
| return parent.getGraphicsConfiguration(); |
| |
| return null; |
| } |
| |
| public final Object getTreeLock() |
| { |
| return treeLock; |
| } |
| |
| public Toolkit getToolkit() |
| { |
| if (peer != null) |
| { |
| Toolkit tk = peer.getToolkit(); |
| if (tk != null) |
| return tk; |
| } |
| if (parent != null) |
| return parent.getToolkit (); |
| return Toolkit.getDefaultToolkit (); |
| } |
| |
| public boolean isValid() |
| { |
| return valid; |
| } |
| |
| /** @since 1.2 */ |
| public boolean isDisplayable() |
| { |
| if (parent != null) |
| return parent.isDisplayable(); |
| return false; |
| } |
| |
| public boolean isVisible() |
| { |
| return visible; |
| } |
| |
| public boolean isShowing() |
| { |
| if (! visible || peer == null) |
| return false; |
| |
| return parent == null ? true : parent.isShowing (); |
| } |
| |
| public boolean isEnabled() |
| { |
| return enabled; |
| } |
| |
| public void setEnabled(boolean b) |
| { |
| this.enabled = b; |
| if (peer != null) |
| peer.setEnabled(b); |
| } |
| |
| /** @deprecated */ |
| public void enable() |
| { |
| setEnabled(true); |
| } |
| |
| /** @deprecated */ |
| public void enable(boolean b) |
| { |
| setEnabled(b); |
| } |
| |
| /** @deprecated */ |
| public void disable() |
| { |
| setEnabled(false); |
| } |
| |
| public boolean isDoubleBuffered() |
| { |
| return false; |
| } |
| |
| /** @since 1.2 */ |
| public void enableInputMethods(boolean enable) |
| { |
| // FIXME |
| } |
| |
| /** @specnote Inspection by subclassing shows that Sun's implementation |
| calls show(boolean) which then calls show() or hide(). It is |
| the show() method that is overriden in subclasses like Window. |
| We do the same to preserve compatibility for subclasses. */ |
| public void setVisible(boolean b) |
| { |
| show (b); |
| } |
| |
| /** @deprecated */ |
| public void show() |
| { |
| if (peer != null) |
| peer.setVisible(true); |
| this.visible = true; |
| } |
| |
| /** @deprecated */ |
| public void show(boolean b) |
| { |
| if (b) |
| show(); |
| else |
| hide(); |
| } |
| |
| /** @deprecated */ |
| public void hide() |
| { |
| if (peer != null) |
| peer.setVisible(false); |
| this.visible = false; |
| } |
| |
| public Color getForeground() |
| { |
| if (foreground != null) |
| return foreground; |
| if (parent != null) |
| return parent.getForeground(); |
| return null; |
| } |
| |
| public void setForeground(Color c) |
| { |
| if (peer != null) |
| peer.setForeground(c); |
| this.foreground = c; |
| } |
| |
| /** @return the background color of the component. null may be |
| returned instead of the actual background color, if this |
| method is called before the component is added to the |
| component hierarchy. */ |
| public Color getBackground() |
| { |
| if (background != null) |
| return background; |
| if (parent != null) |
| return parent.getBackground(); |
| return null; |
| } |
| |
| public void setBackground(Color c) |
| { |
| if (peer != null) |
| peer.setBackground(c); |
| this.background = c; |
| } |
| |
| public Font getFont() |
| { |
| if (font != null) |
| return font; |
| if (parent != null) |
| return parent.getFont(); |
| return null; |
| } |
| |
| public void setFont(Font f) |
| { |
| if (peer != null) |
| peer.setFont(f); |
| this.font = f; |
| } |
| |
| public Locale getLocale() throws IllegalComponentStateException |
| { |
| if (locale != null) |
| return locale; |
| if (parent == null) |
| throw new IllegalComponentStateException |
| ("Component has no parent: Can not determine Locale"); |
| return parent.getLocale(); |
| } |
| |
| public void setLocale(Locale l) |
| { |
| this.locale = l; |
| |
| /* new writing/layout direction perhaps, or make more/less |
| room for localized text labels */ |
| invalidate(); |
| } |
| |
| public ColorModel getColorModel() |
| { |
| GraphicsConfiguration config = getGraphicsConfiguration(); |
| |
| if (config != null) |
| return config.getColorModel(); |
| |
| return getToolkit().getColorModel(); |
| } |
| |
| public Point getLocation() |
| { |
| return new Point(x, y); |
| } |
| |
| public Point getLocationOnScreen() |
| { |
| if (! isShowing ()) |
| throw new IllegalComponentStateException ("component not showing"); |
| |
| // We know peer != null here. |
| return peer.getLocationOnScreen (); |
| } |
| |
| /** @deprecated Use getLocation() instead. */ |
| public Point location() |
| { |
| return getLocation(); |
| } |
| |
| public void setLocation (int x, int y) |
| { |
| if ((this.x == x) && (this.y == y)) |
| return; |
| |
| invalidate(); |
| |
| this.x = x; |
| this.y = y; |
| if (peer != null) |
| peer.setBounds(x, y, width, height); |
| } |
| |
| /** @deprecated */ |
| public void move(int x, int y) |
| { |
| setLocation(x,y); |
| } |
| |
| public void setLocation(Point p) |
| { |
| setLocation(p.x, p.y); |
| } |
| |
| public Dimension getSize() |
| { |
| return new Dimension(width, height); |
| } |
| |
| /** @deprecated */ |
| public Dimension size() |
| { |
| return getSize(); |
| } |
| |
| public void setSize(int width, int height) |
| { |
| if ((this.width == width) && (this.height == height)) |
| return; |
| |
| invalidate(); |
| |
| this.width = width; |
| this.height = height; |
| if (peer != null) |
| peer.setBounds(x, y, width, height); |
| } |
| |
| /** @deprecated */ |
| public void resize(int width, int height) |
| { |
| setSize(width, height); |
| } |
| |
| public void setSize(Dimension d) |
| { |
| setSize(d.width, d.height); |
| } |
| |
| /** @deprecated */ |
| public void resize(Dimension d) |
| { |
| setSize(d.width, d.height); |
| } |
| |
| public Rectangle getBounds() |
| { |
| return new Rectangle (x, y, width, height); |
| } |
| |
| /** @deprecated */ |
| public Rectangle bounds() |
| { |
| return getBounds(); |
| } |
| |
| public void setBounds(int x, int y, int w, int h) |
| { |
| if (this.x == x |
| && this.y == y |
| && this.width == w |
| && this.height == h) |
| return; |
| |
| invalidate(); |
| |
| this.x = x; |
| this.y = y; |
| this.width = w; |
| this.height = h; |
| |
| if (peer != null) |
| peer.setBounds(x, y, w, h); |
| } |
| |
| /** @deprecated */ |
| public void reshape(int x, int y, int width, int height) |
| { |
| setBounds(x, y, width, height); |
| } |
| |
| public void setBounds(Rectangle r) |
| { |
| setBounds(r.x, r.y, r.width, r.height); |
| } |
| |
| /** @since 1.2 */ |
| public int getX() |
| { |
| return x; |
| } |
| |
| /** @since 1.2 */ |
| public int getY() |
| { |
| return y; |
| } |
| |
| /** @since 1.2 */ |
| public int getWidth() |
| { |
| return width; |
| } |
| |
| /** @since 1.2 */ |
| public int getHeight() |
| { |
| return height; |
| } |
| |
| public Rectangle getBounds(Rectangle r) |
| { |
| r.x = this.x; |
| r.y = this.y; |
| r.width = this.width; |
| r.height = this.height; |
| return r; |
| } |
| |
| public Dimension getSize(Dimension d) |
| { |
| d.width = this.width; |
| d.height = this.height; |
| return d; |
| } |
| |
| public Point getLocation(Point p) |
| { |
| p.x = x; |
| p.y = y; |
| return p; |
| } |
| |
| /** @since 1.2 */ |
| public boolean isOpaque() |
| { |
| return !isLightweight(); |
| } |
| |
| /** |
| * Return whether the component is lightweight. |
| * |
| * @return true if component has a peer and and the peer is lightweight. |
| * |
| * @since 1.2 |
| */ |
| public boolean isLightweight() |
| { |
| return (peer != null) && (peer instanceof LightweightPeer); |
| } |
| |
| public Dimension getPreferredSize() |
| { |
| if (peer == null) |
| return new Dimension(width, height); |
| else |
| return peer.getPreferredSize(); |
| } |
| |
| /** @deprecated */ |
| public Dimension preferredSize() |
| { |
| return getPreferredSize(); |
| } |
| |
| public Dimension getMinimumSize() |
| { |
| if (peer == null) |
| return new Dimension(width, height); |
| else |
| return peer.getMinimumSize(); |
| } |
| |
| /** @deprecated */ |
| public Dimension minimumSize() |
| { |
| return getMinimumSize(); |
| } |
| |
| public Dimension getMaximumSize() |
| { |
| return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); |
| } |
| |
| public float getAlignmentX() |
| { |
| return CENTER_ALIGNMENT; |
| } |
| |
| public float getAlignmentY() |
| { |
| return CENTER_ALIGNMENT; |
| } |
| |
| public void doLayout() |
| { |
| // nothing to do unless we're a container |
| } |
| |
| /** @deprecated */ |
| public void layout() |
| { |
| doLayout(); |
| } |
| |
| public void validate() |
| { |
| // nothing to do unless we're a container |
| } |
| |
| public void invalidate() |
| { |
| valid = false; |
| |
| if ((parent != null) && parent.valid) |
| parent.invalidate (); |
| } |
| |
| public Graphics getGraphics() |
| { |
| if (peer != null) |
| { |
| Graphics gfx = peer.getGraphics(); |
| if (gfx != null) |
| return gfx; |
| |
| // create graphics for lightweight: |
| Container parent = getParent(); |
| if (parent != null) |
| { |
| gfx = parent.getGraphics(); |
| Rectangle bounds = getBounds(); |
| gfx.setClip(bounds); |
| gfx.translate(bounds.x, bounds.y); |
| return gfx; |
| } |
| } |
| return null; |
| } |
| |
| public FontMetrics getFontMetrics(Font font) |
| { |
| return getToolkit().getFontMetrics(font); |
| } |
| |
| public void setCursor(Cursor cursor) |
| { |
| this.cursor = cursor; |
| } |
| |
| public Cursor getCursor() |
| { |
| return this.cursor; |
| } |
| |
| public void paint(Graphics g) |
| { |
| } |
| |
| public void update(Graphics g) |
| { |
| paint(g); |
| } |
| |
| public void paintAll(Graphics g) |
| { |
| if (!visible) |
| return; |
| |
| if (peer != null) |
| peer.paint(g); |
| paint(g); |
| } |
| |
| public void repaint() |
| { |
| repaint(0, 0, 0, getWidth(), getHeight()); |
| } |
| |
| public void repaint(long tm) |
| { |
| repaint(tm, 0, 0, getWidth(), getHeight()); |
| } |
| |
| public void repaint(int x, int y, int width, int height) |
| { |
| repaint(0, x, y, width, height); |
| } |
| |
| public void repaint(long tm, int x, int y, int width, int height) |
| { |
| // Handle lightweight repainting by forwarding to native parent |
| if (isLightweight() && (parent != null)) |
| { |
| if (parent != null) |
| parent.repaint(tm, x+getX(), y+getY(), width, height); |
| return; |
| } |
| |
| if (peer != null) |
| peer.repaint(tm, x, y, width, height); |
| } |
| |
| public void print(Graphics g) |
| { |
| paint(g); |
| } |
| |
| public void printAll(Graphics g) |
| { |
| paintAll(g); |
| } |
| |
| public boolean imageUpdate (Image img, int infoflags, int x, int y, |
| int w, int h) |
| { |
| // FIXME |
| return false; |
| } |
| |
| public Image createImage(ImageProducer producer) |
| { |
| // FIXME |
| return null; |
| } |
| |
| public Image createImage(int width, int height) |
| { |
| return getGraphicsConfiguration().createCompatibleImage(width, height); |
| } |
| |
| public boolean prepareImage(Image image, ImageObserver observer) |
| { |
| // FIXME |
| return false; |
| } |
| |
| public boolean prepareImage(Image image, int width, int height, ImageObserver observer) |
| { |
| // FIXME |
| return false; |
| } |
| |
| public int checkImage(Image image, ImageObserver observer) |
| { |
| // FIXME |
| return 0; |
| } |
| |
| public int checkImage (Image image, int width, int height, ImageObserver observer) |
| { |
| if (peer != null) |
| return peer.checkImage (image, width, height, observer); |
| return getToolkit ().checkImage (image, width, height, observer); |
| } |
| |
| public boolean contains (int x, int y) |
| { |
| return (x >= 0) && (y >= 0) && (x < width) && (y < height); |
| } |
| |
| /** @deprecated */ |
| public boolean inside(int x, int y) |
| { |
| return contains(x,y); |
| } |
| |
| public boolean contains(Point p) |
| { |
| return contains(p.x, p.y); |
| } |
| |
| public Component getComponentAt(int x, int y) |
| { |
| if (contains(x,y)) |
| return this; |
| return null; |
| } |
| |
| /** @deprecated */ |
| public Component locate(int x, int y) |
| { |
| return getComponentAt(x, y); |
| } |
| |
| public Component getComponentAt(Point p) |
| { |
| return getComponentAt(p.x, p.y); |
| } |
| |
| /** @deprecated */ |
| public void deliverEvent(Event e) |
| { |
| |
| } |
| |
| /** Forward AWT events to processEvent() if: |
| * - Events have been enabled for this type of event via enableEvents(), |
| * OR: |
| * - There is at least one registered listener for this type of event |
| * |
| * @specnote This method is final, but we need to be able to |
| * override it in order to handle other event types in our |
| * subclasses. The solution is to define a second, non-final |
| * method - dispatchEventImpl() - to actually do the work. |
| * Investigations with Thread.dumpStack() on the dispatch thread |
| * in JDK 1.3 show Sun's implementation is doing the same |
| * thing. |
| */ |
| public final void dispatchEvent(AWTEvent e) |
| { |
| dispatchEventImpl(e); |
| |
| /* Give the peer a chance to handle the event. */ |
| if (peer != null) |
| peer.handleEvent(e); |
| } |
| |
| void dispatchEventImpl(AWTEvent e) |
| { |
| // Make use of event id's in order to avoid multiple instanceof tests. |
| if (e.id <= ComponentEvent.COMPONENT_LAST |
| && e.id >= ComponentEvent.COMPONENT_FIRST |
| && (componentListener != null |
| || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0)) |
| processEvent(e); |
| else if (e.id <= KeyEvent.KEY_LAST |
| && e.id >= KeyEvent.KEY_FIRST |
| && (keyListener != null |
| || (eventMask & AWTEvent.KEY_EVENT_MASK) != 0)) |
| processEvent(e); |
| else if (e.id <= MouseEvent.MOUSE_LAST |
| && e.id >= MouseEvent.MOUSE_FIRST |
| && (mouseListener != null |
| || mouseMotionListener != null |
| || (eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0)) |
| processEvent(e); |
| else if (e.id <= FocusEvent.FOCUS_LAST |
| && e.id >= FocusEvent.FOCUS_FIRST |
| && (focusListener != null |
| || (eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0)) |
| processEvent(e); |
| else if (e.id <= InputMethodEvent.INPUT_METHOD_LAST |
| && e.id >= InputMethodEvent.INPUT_METHOD_FIRST |
| && (inputMethodListener != null |
| || (eventMask & AWTEvent.INPUT_METHOD_EVENT_MASK) != 0)) |
| processEvent(e); |
| else if (e.id <= HierarchyEvent.HIERARCHY_LAST |
| && e.id >= HierarchyEvent.HIERARCHY_FIRST |
| && (hierarchyListener != null |
| || hierarchyBoundsListener != null |
| || (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0)) |
| processEvent(e); |
| else if (e.id <= PaintEvent.PAINT_LAST |
| && e.id >= PaintEvent.PAINT_FIRST |
| && (eventMask & AWTEvent.PAINT_EVENT_MASK) != 0) |
| processEvent(e); |
| } |
| |
| /** @deprecated */ |
| public boolean postEvent(Event e) |
| { |
| return false; |
| } |
| |
| public synchronized void addComponentListener(ComponentListener l) |
| { |
| componentListener = AWTEventMulticaster.add(componentListener, l); |
| if (componentListener != null) |
| enableEvents(AWTEvent.COMPONENT_EVENT_MASK); |
| } |
| |
| public synchronized void removeComponentListener(ComponentListener l) |
| { |
| componentListener = AWTEventMulticaster.remove(componentListener, l); |
| } |
| |
| public synchronized void addFocusListener(FocusListener l) |
| { |
| focusListener = AWTEventMulticaster.add(focusListener, l); |
| if (focusListener != null) |
| enableEvents(AWTEvent.FOCUS_EVENT_MASK); |
| } |
| |
| public synchronized void removeFocusListener(FocusListener l) |
| { |
| focusListener = AWTEventMulticaster.remove(focusListener, l); |
| } |
| |
| /** @since 1.3 */ |
| public synchronized void addHierarchyListener(HierarchyListener l) |
| { |
| hierarchyListener = AWTEventMulticaster.add(hierarchyListener, l); |
| if (hierarchyListener != null) |
| enableEvents(AWTEvent.HIERARCHY_EVENT_MASK); |
| } |
| |
| /** @since 1.3 */ |
| public synchronized void removeHierarchyListener(HierarchyListener l) |
| { |
| hierarchyListener = AWTEventMulticaster.remove(hierarchyListener, l); |
| } |
| |
| /** @since 1.3 */ |
| public synchronized void addHierarchyBoundsListener(HierarchyBoundsListener l) |
| { |
| hierarchyBoundsListener = |
| AWTEventMulticaster.add(hierarchyBoundsListener, l); |
| if (hierarchyBoundsListener != null) |
| enableEvents(AWTEvent.HIERARCHY_EVENT_MASK); |
| } |
| |
| /** @since 1.3 */ |
| public synchronized void |
| removeHierarchyBoundsListener(HierarchyBoundsListener l) |
| { |
| hierarchyBoundsListener = |
| AWTEventMulticaster.remove(hierarchyBoundsListener, l); |
| } |
| |
| public synchronized void addKeyListener(KeyListener l) |
| { |
| keyListener = AWTEventMulticaster.add(keyListener, l); |
| if (keyListener != null) |
| enableEvents(AWTEvent.KEY_EVENT_MASK); |
| } |
| |
| public synchronized void removeKeyListener(KeyListener l) |
| { |
| keyListener = AWTEventMulticaster.remove(keyListener, l); |
| } |
| |
| public synchronized void addMouseListener(MouseListener l) |
| { |
| mouseListener = AWTEventMulticaster.add(mouseListener, l); |
| if (mouseListener != null) |
| enableEvents(AWTEvent.MOUSE_EVENT_MASK); |
| } |
| |
| public synchronized void removeMouseListener(MouseListener l) |
| { |
| mouseListener = AWTEventMulticaster.remove(mouseListener, l); |
| } |
| |
| public synchronized void addMouseMotionListener(MouseMotionListener l) |
| { |
| mouseMotionListener = AWTEventMulticaster.add(mouseMotionListener, l); |
| if (mouseMotionListener != null) |
| enableEvents(AWTEvent.MOUSE_EVENT_MASK); |
| } |
| |
| public synchronized void removeMouseMotionListener(MouseMotionListener l) |
| { |
| mouseMotionListener = AWTEventMulticaster.remove(mouseMotionListener, l); |
| } |
| |
| /** @since 1.2 */ |
| public synchronized void addInputMethodListener(InputMethodListener l) |
| { |
| inputMethodListener = AWTEventMulticaster.add(inputMethodListener, l); |
| if (inputMethodListener != null) |
| enableEvents(AWTEvent.INPUT_METHOD_EVENT_MASK); |
| } |
| |
| /** @since 1.2 */ |
| public synchronized void removeInputMethodListener(InputMethodListener l) |
| { |
| inputMethodListener = AWTEventMulticaster.remove(inputMethodListener, l); |
| } |
| |
| /** Returns all registered EventListers of the given listenerType. |
| * listenerType must be a subclass of EventListener, or a |
| * ClassClassException is thrown. |
| * @since 1.3 |
| */ |
| public EventListener[] getListeners(Class listenerType) |
| { |
| if (listenerType == ComponentListener.class) |
| return getListenersImpl(listenerType, componentListener); |
| else if (listenerType == FocusListener.class) |
| return getListenersImpl(listenerType, focusListener); |
| else if (listenerType == KeyListener.class) |
| return getListenersImpl(listenerType, keyListener); |
| else if (listenerType == MouseListener.class) |
| return getListenersImpl(listenerType, mouseListener); |
| else if (listenerType == MouseMotionListener.class) |
| return getListenersImpl(listenerType, mouseMotionListener); |
| else if (listenerType == InputMethodListener.class) |
| return getListenersImpl(listenerType, inputMethodListener); |
| else if (listenerType == HierarchyListener.class) |
| return getListenersImpl(listenerType, hierarchyListener); |
| else if (listenerType == HierarchyBoundsListener.class) |
| return getListenersImpl(listenerType, hierarchyBoundsListener); |
| else |
| return getListenersImpl(listenerType, null); |
| } |
| |
| static EventListener[] getListenersImpl(Class listenerType, EventListener el) |
| { |
| if (! EventListener.class.isAssignableFrom(listenerType)) |
| throw new ClassCastException(); |
| |
| Vector v = new Vector(); |
| if (el != null) |
| getListenerList (el, v); |
| EventListener[] el_a = (EventListener[]) Array.newInstance(listenerType, |
| v.size()); |
| v.copyInto(el_a); |
| return el_a; |
| } |
| |
| static void getListenerList(EventListener el, Vector v) |
| { |
| if (el instanceof AWTEventMulticaster) |
| { |
| AWTEventMulticaster mc = (AWTEventMulticaster) el; |
| getListenerList(mc.a, v); |
| getListenerList(mc.b, v); |
| } |
| else |
| v.addElement(el); |
| } |
| |
| // The input method framework is currently unimplemented. |
| // /** @since 1.2 */ |
| // |
| //public InputMethodRequests getInputMethodRequests() |
| // |
| // /** @since 1.2 */ |
| // |
| // public InputContext getInputContext() |
| |
| protected final void enableEvents(long eventsToEnable) |
| { |
| eventMask |= eventsToEnable; |
| // TODO: Unlike Sun's implementation, I think we should try and |
| // enable/disable events at the peer (gtk/X) level. This will avoid |
| // clogging the event pipeline with useless mousemove events that |
| // we arn't interested in, etc. This will involve extending the peer |
| // interface, but thats okay because the peer interfaces have been |
| // deprecated for a long time, and no longer feature in the |
| // API specification at all. |
| |
| if (isLightweight() && (parent != null)) |
| parent.enableEvents(eventsToEnable); |
| else if (peer != null) |
| peer.setEventMask (eventMask); |
| } |
| |
| protected final void disableEvents(long eventsToDisable) |
| { |
| eventMask &= ~eventsToDisable; |
| // forward new event mask to peer? |
| } |
| |
| /** coalesceEvents is called by the EventQueue if two events with the same |
| * event id are queued. Returns a new combined event, or null if no |
| * combining is done. |
| */ |
| protected AWTEvent coalesceEvents(AWTEvent existingEvent, AWTEvent newEvent) |
| { |
| switch (existingEvent.id) |
| { |
| case MouseEvent.MOUSE_MOVED: |
| case MouseEvent.MOUSE_DRAGGED: |
| // Just drop the old (intermediate) event and return the new one. |
| return newEvent; |
| case PaintEvent.PAINT: |
| case PaintEvent.UPDATE: |
| return coalescePaintEvents((PaintEvent) existingEvent, |
| (PaintEvent) newEvent); |
| } |
| return null; |
| } |
| |
| /** |
| * Coalesce paint events. Current heuristic is: Merge if the union of |
| * areas is less than twice that of the sum of the areas. The X server |
| * tend to create a lot of paint events that are adjacent but not |
| * overlapping. |
| * |
| * <pre> |
| * +------+ |
| * | +-----+ ...will be merged |
| * | | | |
| * | | | |
| * +------+ | |
| * +-----+ |
| * |
| * +---------------+--+ |
| * | | | ...will not be merged |
| * +---------------+ | |
| * | | |
| * | | |
| * | | |
| * | | |
| * | | |
| * +--+ |
| * </pre> |
| */ |
| |
| private PaintEvent coalescePaintEvents(PaintEvent queuedEvent, |
| PaintEvent newEvent) |
| { |
| Rectangle r1 = queuedEvent.getUpdateRect(); |
| Rectangle r2 = newEvent.getUpdateRect(); |
| Rectangle union = r1.union(r2); |
| |
| int r1a = r1.width * r1.height; |
| int r2a = r2.width * r2.height; |
| int ua = union.width * union.height; |
| |
| if (ua > (r1a+r2a)*2) |
| return null; |
| /* The 2 factor should maybe be reconsidered. Perhaps 3/2 |
| would be better? */ |
| |
| newEvent.setUpdateRect(union); |
| return newEvent; |
| } |
| |
| |
| |
| |
| /** Forward event to the appropriate processXXXEvent method based on the |
| * event type. |
| */ |
| protected void processEvent(AWTEvent e) |
| { |
| |
| /* Note: the order of these if statements are |
| important. Subclasses must be checked first. Eg. MouseEvent |
| must be checked before ComponentEvent, since a MouseEvent |
| object is also an instance of a ComponentEvent. */ |
| |
| if (e instanceof FocusEvent) |
| processFocusEvent((FocusEvent) e); |
| else if (e instanceof PaintEvent) |
| processPaintEvent((PaintEvent) e); |
| else if (e instanceof MouseEvent) |
| { |
| if (e.id == MouseEvent.MOUSE_MOVED |
| || e.id == MouseEvent.MOUSE_DRAGGED) |
| processMouseMotionEvent((MouseEvent) e); |
| else |
| processMouseEvent((MouseEvent) e); |
| } |
| else if (e instanceof ComponentEvent) |
| processComponentEvent((ComponentEvent) e); |
| else if (e instanceof KeyEvent) |
| processKeyEvent((KeyEvent) e); |
| else if (e instanceof InputMethodEvent) |
| processInputMethodEvent((InputMethodEvent) e); |
| else if (e instanceof HierarchyEvent) |
| { |
| if (e.id == HierarchyEvent.HIERARCHY_CHANGED) |
| processHierarchyEvent((HierarchyEvent) e); |
| else |
| processHierarchyBoundsEvent((HierarchyEvent) e); |
| } |
| } |
| |
| protected void processComponentEvent(ComponentEvent e) |
| { |
| if (componentListener == null) |
| return; |
| switch (e.id) |
| { |
| case ComponentEvent.COMPONENT_HIDDEN: |
| componentListener.componentHidden(e); |
| break; |
| |
| case ComponentEvent.COMPONENT_MOVED: |
| componentListener.componentMoved(e); |
| break; |
| |
| case ComponentEvent.COMPONENT_RESIZED: |
| componentListener.componentResized(e); |
| break; |
| |
| case ComponentEvent.COMPONENT_SHOWN: |
| componentListener.componentShown(e); |
| break; |
| } |
| } |
| |
| protected void processFocusEvent(FocusEvent e) |
| { |
| if (focusListener == null) |
| return; |
| switch (e.id) |
| { |
| case FocusEvent.FOCUS_GAINED: |
| focusListener.focusGained(e); |
| break; |
| case FocusEvent.FOCUS_LOST: |
| focusListener.focusLost(e); |
| break; |
| } |
| } |
| |
| protected void processKeyEvent(KeyEvent e) |
| { |
| if (keyListener == null) |
| return; |
| switch (e.id) |
| { |
| case KeyEvent.KEY_PRESSED: |
| keyListener.keyPressed(e); |
| break; |
| case KeyEvent.KEY_RELEASED: |
| keyListener.keyReleased(e); |
| break; |
| case KeyEvent.KEY_TYPED: |
| keyListener.keyTyped(e); |
| break; |
| } |
| } |
| |
| protected void processMouseEvent(MouseEvent e) |
| { |
| if (mouseListener == null) |
| return; |
| switch (e.id) |
| { |
| case MouseEvent.MOUSE_CLICKED: |
| mouseListener.mouseClicked(e); |
| break; |
| case MouseEvent.MOUSE_ENTERED: |
| mouseListener.mouseEntered(e); |
| break; |
| case MouseEvent.MOUSE_EXITED: |
| mouseListener.mouseExited(e); |
| break; |
| case MouseEvent.MOUSE_PRESSED: |
| mouseListener.mousePressed(e); |
| break; |
| case MouseEvent.MOUSE_RELEASED: |
| mouseListener.mouseReleased(e); |
| break; |
| } |
| } |
| |
| protected void processMouseMotionEvent(MouseEvent e) |
| { |
| if (mouseMotionListener == null) |
| return; |
| switch (e.id) |
| { |
| case MouseEvent.MOUSE_DRAGGED: |
| mouseMotionListener.mouseDragged(e); |
| break; |
| case MouseEvent.MOUSE_MOVED: |
| mouseMotionListener.mouseMoved(e); |
| break; |
| } |
| } |
| |
| /** @since 1.2 */ |
| protected void processInputMethodEvent(InputMethodEvent e) |
| { |
| if (inputMethodListener == null) |
| return; |
| switch (e.id) |
| { |
| case InputMethodEvent.CARET_POSITION_CHANGED: |
| inputMethodListener.caretPositionChanged(e); |
| break; |
| case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED: |
| inputMethodListener.inputMethodTextChanged(e); |
| break; |
| } |
| } |
| |
| /** @since 1.3 */ |
| protected void processHierarchyEvent(HierarchyEvent e) |
| { |
| if (hierarchyListener == null) |
| return; |
| if (e.id == HierarchyEvent.HIERARCHY_CHANGED) |
| hierarchyListener.hierarchyChanged(e); |
| } |
| |
| /** @since 1.3 */ |
| protected void processHierarchyBoundsEvent(HierarchyEvent e) |
| { |
| if (hierarchyBoundsListener == null) |
| return; |
| switch (e.id) |
| { |
| case HierarchyEvent.ANCESTOR_MOVED: |
| hierarchyBoundsListener.ancestorMoved(e); |
| break; |
| case HierarchyEvent.ANCESTOR_RESIZED: |
| hierarchyBoundsListener.ancestorResized(e); |
| break; |
| } |
| } |
| |
| private void processPaintEvent(PaintEvent event) |
| { |
| // Can't do graphics without peer |
| if (peer == null) |
| return; |
| |
| Graphics gfx = getGraphics(); |
| Shape clip = event.getUpdateRect(); |
| gfx.setClip(clip); |
| |
| switch (event.id) |
| { |
| case PaintEvent.PAINT: |
| paint(gfx); |
| break; |
| case PaintEvent.UPDATE: |
| update(gfx); |
| break; |
| default: |
| throw new IllegalArgumentException("unknown paint event"); |
| } |
| } |
| |
| /** @deprecated */ |
| public boolean handleEvent(Event evt) |
| { |
| return false; |
| } |
| |
| /** @deprecated */ |
| public boolean mouseDown(Event evt, int x, int y) |
| { |
| return false; |
| } |
| |
| /** @deprecated */ |
| public boolean mouseDrag(Event evt, int x, int y) |
| { |
| return false; |
| } |
| |
| /** @deprecated */ |
| public boolean mouseUp(Event evt, int x, int y) |
| { |
| return false; |
| } |
| |
| /** @deprecated */ |
| public boolean mouseMove(Event evt, int x, int y) |
| { |
| return false; |
| } |
| |
| /** @deprecated */ |
| public boolean mouseEnter(Event evt, int x, int y) |
| { |
| return false; |
| } |
| |
| /** @deprecated */ |
| public boolean mouseExit(Event evt, int x, int y) |
| { |
| return false; |
| } |
| |
| /** @deprecated */ |
| public boolean keyDown(Event evt, int key) |
| { |
| return false; |
| } |
| |
| /** @deprecated */ |
| public boolean keyUp(Event evt, int key) |
| { |
| return false; |
| } |
| |
| /** @deprecated */ |
| public boolean action(Event evt, Object what) |
| { |
| return false; |
| } |
| |
| public void addNotify() |
| { |
| if (peer == null) |
| peer = getToolkit().createComponent(this); |
| |
| /* Add notify children using a template method, so that it is |
| possible to ensure that the new event mask delivered to the |
| peer. */ |
| addNotifyContainerChildren(); |
| |
| /* Now that all the children has gotten their peers, we should |
| have the event mask needed for this component and its |
| lightweight subcomponents. */ |
| |
| peer.setEventMask(eventMask); |
| |
| /* We do not invalidate here, but rather leave that job up to |
| the peer. For efficiency, the peer can choose not to |
| invalidate if it is happy with the current dimensions, |
| etc. */ |
| } |
| |
| void addNotifyContainerChildren() |
| { |
| // nothing to do unless we're a container |
| } |
| |
| public void removeNotify() |
| { |
| if (peer != null) |
| peer.dispose(); |
| peer = null; |
| } |
| |
| /** @deprecated */ |
| public boolean gotFocus(Event evt, Object what) |
| { |
| return false; |
| } |
| |
| /** @deprecated */ |
| public boolean lostFocus(Event evt, Object what) |
| { |
| return false; |
| } |
| |
| public boolean isFocusTraversable() |
| { |
| return enabled && visible && (peer == null || peer.isFocusTraversable ()); |
| } |
| |
| public void requestFocus() |
| { |
| // If there's no peer then this component can't get the focus. We |
| // treat it as a silent rejection of the request. |
| if (peer != null) |
| peer.requestFocus (); |
| } |
| |
| // This method is used to implement transferFocus(). |
| // CHILD is the child making the request. |
| // This is overridden by Container; when called for an ordinary |
| // component there is no child and so we always return null. |
| Component findNextFocusComponent (Component child) |
| { |
| return null; |
| } |
| |
| public void transferFocus() |
| { |
| Component next; |
| if (parent == null) |
| next = findNextFocusComponent (null); |
| else |
| next = parent.findNextFocusComponent (this); |
| if (next != null && next != this) |
| next.requestFocus (); |
| } |
| |
| /** @deprecated */ |
| public void nextFocus() |
| { |
| transferFocus(); |
| } |
| |
| /** @since 1.2 */ |
| public boolean hasFocus() |
| { |
| return hasFocus; |
| } |
| |
| public synchronized void add(PopupMenu popup) |
| { |
| if (popups == null) |
| popups = new Vector(); |
| popups.addElement(popup); |
| } |
| |
| public synchronized void remove(MenuComponent popup) |
| { |
| popups.removeElement(popup); |
| } |
| |
| protected String paramString() |
| { |
| StringBuffer param = new StringBuffer(); |
| String name = getName(); |
| if (name != null) |
| { |
| param.append(name); |
| param.append(","); |
| } |
| param.append(width); |
| param.append("x"); |
| param.append(height); |
| param.append("+"); |
| param.append(x); |
| param.append("+"); |
| param.append(y); |
| |
| if (!isValid()) |
| param.append(",invalid"); |
| if (!isVisible()) |
| param.append(",invisible"); |
| if (!isEnabled()) |
| param.append(",disabled"); |
| if (!isOpaque()) |
| param.append(",translucent"); |
| if (isDoubleBuffered()) |
| param.append(",doublebuffered"); |
| |
| return param.toString(); |
| } |
| |
| public String toString() |
| { |
| return this.getClass().getName() + "[" + paramString() + "]"; |
| } |
| |
| public void list () |
| { |
| list (System.out, 0); |
| } |
| |
| public void list (PrintStream out) |
| { |
| list (out, 0); |
| } |
| |
| public void list (PrintStream out, int indent) |
| { |
| for (int i = 0; i < indent; ++i) |
| out.print (' '); |
| out.println (toString ()); |
| } |
| |
| public void list (PrintWriter out) |
| { |
| list (out, 0); |
| } |
| |
| public void list (PrintWriter out, int indent) |
| { |
| for (int i = 0; i < indent; ++i) |
| out.print (' '); |
| out.println (toString ()); |
| } |
| |
| public void addPropertyChangeListener(PropertyChangeListener listener) |
| { |
| if (changeSupport == null) |
| changeSupport = new PropertyChangeSupport(this); |
| changeSupport.addPropertyChangeListener(listener); |
| } |
| |
| public void removePropertyChangeListener(PropertyChangeListener listener) |
| { |
| if (changeSupport != null) |
| changeSupport.removePropertyChangeListener(listener); |
| } |
| |
| public void addPropertyChangeListener(String propertyName, |
| PropertyChangeListener listener) |
| { |
| if (changeSupport == null) |
| changeSupport = new PropertyChangeSupport(this); |
| changeSupport.addPropertyChangeListener(propertyName, listener); |
| } |
| |
| public void removePropertyChangeListener(String propertyName, |
| PropertyChangeListener listener) |
| { |
| if (changeSupport != null) |
| changeSupport.removePropertyChangeListener(propertyName, listener); |
| } |
| |
| protected void firePropertyChange(String propertyName, Object oldValue, |
| Object newValue) |
| { |
| if (changeSupport != null) |
| changeSupport.firePropertyChange(propertyName, oldValue, newValue); |
| } |
| |
| public void setComponentOrientation(ComponentOrientation o) |
| { |
| orientation = o; |
| } |
| |
| public ComponentOrientation getComponentOrientation() |
| { |
| return orientation; |
| } |
| |
| /* |
| public AccessibleContext getAccessibleContext() |
| { |
| return accessibleContext; |
| } |
| */ |
| } |