001: /*
002: * @(#)HeavyweightComponentXWindow.java 1.15 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027: package java.awt;
028:
029: import java.awt.event.PaintEvent;
030: import java.awt.event.ComponentListener;
031: import java.awt.event.ComponentEvent;
032: import java.awt.event.ContainerListener;
033: import java.awt.event.ContainerEvent;
034: import java.util.ArrayList;
035: import java.util.Iterator;
036:
037: /** The X window used by a component, that is traditionally heavyweight, to get mouse events from the X server.
038: This winow represents an InputOutput
039: window in X (an opaque window that can be used to select and receive events). This is required for maximum
040: compatiability with applications/applets that assume AWT components are heavyweight. Heavyweight components
041: generate their own paint events and also appear in front of lightweights. Some programs may require these
042: assumptions in order to work properly so by providing a heavyweight window we can maintain maximum
043: compatiability.
044: @version 1.1, 10/22/01
045: @author Nicholas Allen*/
046:
047: class HeavyweightComponentXWindow extends ComponentXWindow implements
048: ComponentListener, ContainerListener {
049: HeavyweightComponentXWindow(Component component) {
050: super (component);
051: }
052:
053: void create() {
054: // Find parent whose X window is also a heavyweight X window. This is necessary because
055: // X does not allow an InputOutput window to be a child of an InputOnly window. We need
056: // to listen for lightweight parent moves/hides because we are not a child of these but
057: // as far as Java is concerned we are.
058:
059: Container parent = component.parent;
060: // If the parent is a scrollpane then we want to create our X window as a child of the
061: // viewport and not the scrollpane itself. We must only do this if the component is not
062: // the viewport or the scroll bars for the scrollpane as they should be made children of
063: // the scrollpane itself and not the viewport.
064:
065: if (parent instanceof ScrollPane) {
066: ScrollPane scrollPane = (ScrollPane) parent;
067: if (component != scrollPane.viewport
068: && component != scrollPane.horizScrollbar
069: && component != scrollPane.vertScrollbar) {
070: // Create the viewport X window that we will be added to instead of the scrollpane's.
071:
072: scrollPane.viewport.parent = scrollPane;
073: scrollPane.viewport.addNotify();
074: parent = scrollPane.viewport;
075: }
076: } else {
077: while (parent.isLightweight()) {
078: parent.addComponentListener(this );
079: parent.addContainerListener(this );
080: parent = parent.parent;
081: }
082: parent.addContainerListener(this );
083: }
084: heavyweightParent = parent;
085: this .windowID = create(parent.xwindow.windowID);
086: }
087:
088: private native int create(int parent);
089:
090: void dispose() {
091: removeReferences();
092: super .dispose();
093: }
094:
095: native void setMouseEventMask(long mask);
096:
097: final native void setBackground(Color color);
098:
099: /** Called by the native code when an area of the X Window is exposed.
100: This posts a paint event into Java's event queue for processing by Java
101: so that the exposed area is redrawn. */
102:
103: void postPaintEvent(int x, int y, int width, int height) {
104: Toolkit.getEventQueue().postEvent(
105: new PaintEvent(component, PaintEvent.PAINT,
106: new Rectangle(x, y, width, height)));
107: }
108:
109: void setBounds(int x, int y, int width, int height) {
110: // Translate into heavyweight parent's coordinates.
111:
112: Container parent = component.parent;
113: while (parent != null) {
114: if (parent.xwindow instanceof HeavyweightComponentXWindow) {
115: // X does not allow window of width or height of 0 so if the component has these
116: // dimensions then we unmap the XWindow.
117:
118: if (width == 0 || height == 0) {
119: unmap();
120: zeroSize = true;
121: } else {
122: // If this is a top level delegate's x window then it is a child of the delegate
123: // source's x window and so we always position it a 0,0.
124:
125: if (component.delegateSource != null) {
126: x = 0;
127: y = 0;
128: } else {
129: if (parent.xwindow instanceof WindowXWindow) {
130: x -= ((WindowXWindow) parent.xwindow).leftBorder;
131: y -= ((WindowXWindow) parent.xwindow).topBorder;
132: }
133: }
134: setBoundsNative(x, y, width, height);
135: zeroSize = false;
136: // Because the X window could have been unmapped by setting the size to 0
137: // we remap it again if the component is showing.
138:
139: if (component.visible)
140: map();
141: }
142: return;
143: }
144: x += parent.x;
145: y += parent.y;
146: parent = parent.parent;
147: }
148: }
149:
150: /**
151: * Invoked when the component's size changes.
152: */
153: public void componentResized(ComponentEvent e) {
154: }
155:
156: /**
157: * Invoked when the component's position changes.
158: */
159: public void componentMoved(ComponentEvent e) {
160: setBounds(component.x, component.y, component.width,
161: component.height);
162: }
163:
164: /**
165: * Invoked when the component has been made visible.
166: */
167: public void componentShown(ComponentEvent e) {
168: if (component.isShowing())
169: map();
170: }
171:
172: /**
173: * Invoked when the component has been made invisible.
174: */
175: public void componentHidden(ComponentEvent e) {
176: unmap();
177: }
178:
179: /**
180: * Invoked when a component has been added to the container.
181: */
182: public void componentAdded(ContainerEvent e) {
183: }
184:
185: /**
186: * Invoked when a component has been removed from the container.
187: */
188: public void componentRemoved(ContainerEvent e) {
189: Component c = e.getChild();
190: if (c == component)
191: removeReferences();
192: else if (lightweightParents.contains(c))
193: removeReferences();
194: }
195:
196: private void removeReferences() {
197: Iterator i = lightweightParents.iterator();
198: while (i.hasNext()) {
199: Container c = (Container) i.next();
200: c.removeComponentListener(this );
201: c.removeContainerListener(this );
202: }
203: if (heavyweightParent != null)
204: heavyweightParent.removeContainerListener(this );
205: }
206:
207: private java.util.List lightweightParents = new ArrayList(4);
208: private Container heavyweightParent;
209: }
|