1 /*
2 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
24 */
25
26 package sun.lwawt;
27
28 import sun.awt.SunGraphicsCallback;
29 import sun.java2d.pipe.Region;
30
31 import java.awt.Color;
32 import java.awt.Container;
33 import java.awt.Font;
34 import java.awt.Graphics;
35 import java.awt.Insets;
36 import java.awt.Rectangle;
37 import java.awt.peer.ContainerPeer;
38 import java.util.LinkedList;
39 import java.util.List;
40
41 import javax.swing.JComponent;
42
43 abstract class LWContainerPeer<T extends Container, D extends JComponent>
44 extends LWCanvasPeer<T, D>
45 implements ContainerPeer
46 {
47 // List of child peers sorted by z-order from bottom-most
48 // to top-most
49 private List<LWComponentPeer> childPeers =
50 new LinkedList<LWComponentPeer>();
51
52 LWContainerPeer(T target, PlatformComponent platformComponent) {
53 super(target, platformComponent);
54 }
55
56 void addChildPeer(LWComponentPeer child) {
57 synchronized (getPeerTreeLock()) {
58 addChildPeer(child, childPeers.size());
59 }
60 }
61
62 void addChildPeer(LWComponentPeer child, int index) {
63 synchronized (getPeerTreeLock()) {
64 childPeers.add(index, child);
65 }
66 // TODO: repaint
67 }
68
69 void removeChildPeer(LWComponentPeer child) {
70 synchronized (getPeerTreeLock()) {
71 childPeers.remove(child);
72 }
73 // TODO: repaint
74 }
75
76 // Used by LWComponentPeer.setZOrder()
77 void setChildPeerZOrder(LWComponentPeer peer, LWComponentPeer above) {
78 synchronized (getPeerTreeLock()) {
79 childPeers.remove(peer);
80 int index = (above != null) ? childPeers.indexOf(above) : childPeers.size();
81 if (index >= 0) {
82 childPeers.add(index, peer);
83 } else {
84 // TODO: log
85 }
86 }
87 // TODO: repaint
88 }
89
90 // ---- PEER METHODS ---- //
91
92 /*
93 * Overridden in LWWindowPeer.
94 */
95 @Override
96 public Insets getInsets() {
97 return new Insets(0, 0, 0, 0);
98 }
99
100 @Override
101 public void beginValidate() {
102 // TODO: it seems that begin/endValidate() is only useful
103 // for heavyweight windows, when a batch movement for
104 // child windows occurs. That's why no-op
105 }
106 @Override
107 public void endValidate() {
108 // TODO: it seems that begin/endValidate() is only useful
109 // for heavyweight windows, when a batch movement for
110 // child windows occurs. That's why no-op
111 }
112
113 @Override
114 public void beginLayout() {
115 // Skip all painting till endLayout()
116 setLayouting(true);
117 }
118 @Override
119 public void endLayout() {
120 setLayouting(false);
121
122 // Post an empty event to flush all the pending target paints
123 postPaintEvent(0, 0, 0, 0);
124 }
125
126 // ---- PEER NOTIFICATIONS ---- //
127
128 /*
129 * Returns a copy of the childPeer collection.
130 */
131 protected List<LWComponentPeer> getChildren() {
132 synchronized (getPeerTreeLock()) {
133 Object copy = ((LinkedList)childPeers).clone();
134 return (List<LWComponentPeer>)copy;
135 }
136 }
137
138 @Override
139 public final Region getVisibleRegion() {
140 return cutChildren(super.getVisibleRegion(), null);
141 }
142
143 /**
144 * Removes bounds of children above specific child from the region. If above
145 * is null removes all bounds of children.
146 */
147 protected final Region cutChildren(Region r, final LWComponentPeer above) {
148 boolean aboveFound = above == null;
149 for (final LWComponentPeer child : getChildren()) {
150 if (!aboveFound && child == above) {
151 aboveFound = true;
152 continue;
153 }
154 if (aboveFound) {
155 if(child.isVisible()){
156 final Rectangle cb = child.getBounds();
157 final Region cr = child.getRegion();
158 final Region tr = cr.getTranslatedRegion(cb.x, cb.y);
159 r = r.getDifference(tr.getIntersection(getContentSize()));
160 }
161 }
162 }
163 return r;
164 }
165
166 // ---- UTILITY METHODS ---- //
167
168 /**
169 * Finds a top-most visible component for the given point. The location is
170 * specified relative to the peer's parent.
171 */
172 @Override
173 public final LWComponentPeer findPeerAt(int x, int y) {
174 LWComponentPeer peer = super.findPeerAt(x, y);
175 final Rectangle r = getBounds();
176 // Translate to this container's coordinates to pass to children
177 x -= r.x;
178 y -= r.y;
179 if (peer != null && getContentSize().contains(x, y)) {
180 synchronized (getPeerTreeLock()) {
181 for (int i = childPeers.size() - 1; i >= 0; --i) {
182 LWComponentPeer p = childPeers.get(i).findPeerAt(x, y);
183 if (p != null) {
184 peer = p;
185 break;
186 }
187 }
188 }
189 }
190 return peer;
191 }
192
193 /*
194 * Called by the container when any part of this peer or child
195 * peers should be repainted
196 */
197 @Override
198 public final void repaintPeer(final Rectangle r) {
199 final Rectangle toPaint = getSize().intersection(r);
200 if (!isShowing() || toPaint.isEmpty()) {
201 return;
202 }
203 // First, post the PaintEvent for this peer
204 super.repaintPeer(toPaint);
205 // Second, handle all the children
206 // Use the straight order of children, so the bottom
207 // ones are painted first
208 repaintChildren(toPaint);
209 }
210
211 /*
212 * Paints all the child peers in the straight z-order, so the
213 * bottom-most ones are painted first.
214 */
215 private void repaintChildren(final Rectangle r) {
216 final Rectangle content = getContentSize();
217 for (final LWComponentPeer child : getChildren()) {
218 final Rectangle childBounds = child.getBounds();
219 Rectangle toPaint = r.intersection(childBounds);
220 toPaint = toPaint.intersection(content);
221 toPaint.translate(-childBounds.x, -childBounds.y);
222 child.repaintPeer(toPaint);
223 }
224 }
225
226 protected Rectangle getContentSize() {
227 return getSize();
228 }
229
230 @Override
231 public void setEnabled(final boolean e) {
232 super.setEnabled(e);
233 for (final LWComponentPeer child : getChildren()) {
234 child.setEnabled(e && child.getTarget().isEnabled());
235 }
236 }
237
238 @Override
239 public void setBackground(final Color c) {
240 for (final LWComponentPeer child : getChildren()) {
241 if (!child.getTarget().isBackgroundSet()) {
242 child.setBackground(c);
243 }
244 }
245 super.setBackground(c);
246 }
247
248 @Override
249 public void setForeground(final Color c) {
250 for (final LWComponentPeer child : getChildren()) {
251 if (!child.getTarget().isForegroundSet()) {
252 child.setForeground(c);
253 }
254 }
255 super.setForeground(c);
256 }
257
258 @Override
259 public void setFont(final Font f) {
260 for (final LWComponentPeer child : getChildren()) {
261 if (!child.getTarget().isFontSet()) {
262 child.setFont(f);
263 }
264 }
265 super.setFont(f);
266 }
267
268 @Override
269 public final void paint(final Graphics g) {
270 super.paint(g);
271 SunGraphicsCallback.PaintHeavyweightComponentsCallback.getInstance()
272 .runComponents(getTarget().getComponents(), g,
273 SunGraphicsCallback.LIGHTWEIGHTS
274 | SunGraphicsCallback.HEAVYWEIGHTS);
275 }
276
277 @Override
278 public final void print(final Graphics g) {
279 super.print(g);
280 SunGraphicsCallback.PrintHeavyweightComponentsCallback.getInstance()
|
1 /*
2 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
24 */
25
26 package sun.lwawt;
27
28 import sun.awt.SunGraphicsCallback;
29 import sun.java2d.pipe.Region;
30
31 import java.awt.Color;
32 import java.awt.Container;
33 import java.awt.Font;
34 import java.awt.Graphics;
35 import java.awt.Insets;
36 import java.awt.Rectangle;
37 import java.awt.peer.ContainerPeer;
38 import java.util.LinkedList;
39 import java.util.List;
40
41 import javax.swing.JComponent;
42
43 abstract class LWContainerPeer<T extends Container, D extends JComponent>
44 extends LWCanvasPeer<T, D> implements ContainerPeer {
45
46 /**
47 * List of child peers sorted by z-order from bottom-most to top-most.
48 */
49 private final List<LWComponentPeer<?, ?>> childPeers = new LinkedList<>();
50
51 LWContainerPeer(final T target, final PlatformComponent platformComponent) {
52 super(target, platformComponent);
53 }
54
55 final void addChildPeer(final LWComponentPeer<?, ?> child) {
56 synchronized (getPeerTreeLock()) {
57 childPeers.add(childPeers.size(), child);
58 // TODO: repaint
59 }
60 }
61
62 final void removeChildPeer(final LWComponentPeer<?, ?> child) {
63 synchronized (getPeerTreeLock()) {
64 childPeers.remove(child);
65 }
66 // TODO: repaint
67 }
68
69 // Used by LWComponentPeer.setZOrder()
70 final void setChildPeerZOrder(final LWComponentPeer<?, ?> peer,
71 final LWComponentPeer<?, ?> above) {
72 synchronized (getPeerTreeLock()) {
73 childPeers.remove(peer);
74 int index = (above != null) ? childPeers.indexOf(above) : childPeers.size();
75 if (index >= 0) {
76 childPeers.add(index, peer);
77 } else {
78 // TODO: log
79 }
80 }
81 // TODO: repaint
82 }
83
84 // ---- PEER METHODS ---- //
85
86 /*
87 * Overridden in LWWindowPeer.
88 */
89 @Override
90 public Insets getInsets() {
91 return new Insets(0, 0, 0, 0);
92 }
93
94 @Override
95 public final void beginValidate() {
96 // TODO: it seems that begin/endValidate() is only useful
97 // for heavyweight windows, when a batch movement for
98 // child windows occurs. That's why no-op
99 }
100
101 @Override
102 public final void endValidate() {
103 // TODO: it seems that begin/endValidate() is only useful
104 // for heavyweight windows, when a batch movement for
105 // child windows occurs. That's why no-op
106 }
107
108 @Override
109 public final void beginLayout() {
110 // Skip all painting till endLayout()
111 setLayouting(true);
112 }
113
114 @Override
115 public final void endLayout() {
116 setLayouting(false);
117
118 // Post an empty event to flush all the pending target paints
119 postPaintEvent(0, 0, 0, 0);
120 }
121
122 // ---- PEER NOTIFICATIONS ---- //
123
124 /**
125 * Returns a copy of the childPeer collection.
126 */
127 @SuppressWarnings("unchecked")
128 final List<LWComponentPeer<?, ?>> getChildren() {
129 synchronized (getPeerTreeLock()) {
130 Object copy = ((LinkedList<?>) childPeers).clone();
131 return (List<LWComponentPeer<?, ?>>) copy;
132 }
133 }
134
135 @Override
136 final Region getVisibleRegion() {
137 return cutChildren(super.getVisibleRegion(), null);
138 }
139
140 /**
141 * Removes bounds of children above specific child from the region. If above
142 * is null removes all bounds of children.
143 */
144 final Region cutChildren(Region r, final LWComponentPeer<?, ?> above) {
145 boolean aboveFound = above == null;
146 for (final LWComponentPeer<?, ?> child : getChildren()) {
147 if (!aboveFound && child == above) {
148 aboveFound = true;
149 continue;
150 }
151 if (aboveFound) {
152 if(child.isVisible()){
153 final Rectangle cb = child.getBounds();
154 final Region cr = child.getRegion();
155 final Region tr = cr.getTranslatedRegion(cb.x, cb.y);
156 r = r.getDifference(tr.getIntersection(getContentSize()));
157 }
158 }
159 }
160 return r;
161 }
162
163 // ---- UTILITY METHODS ---- //
164
165 /**
166 * Finds a top-most visible component for the given point. The location is
167 * specified relative to the peer's parent.
168 */
169 @Override
170 final LWComponentPeer<?, ?> findPeerAt(int x, int y) {
171 LWComponentPeer<?, ?> peer = super.findPeerAt(x, y);
172 final Rectangle r = getBounds();
173 // Translate to this container's coordinates to pass to children
174 x -= r.x;
175 y -= r.y;
176 if (peer != null && getContentSize().contains(x, y)) {
177 synchronized (getPeerTreeLock()) {
178 for (int i = childPeers.size() - 1; i >= 0; --i) {
179 LWComponentPeer<?, ?> p = childPeers.get(i).findPeerAt(x, y);
180 if (p != null) {
181 peer = p;
182 break;
183 }
184 }
185 }
186 }
187 return peer;
188 }
189
190 /*
191 * Called by the container when any part of this peer or child
192 * peers should be repainted
193 */
194 @Override
195 final void repaintPeer(final Rectangle r) {
196 final Rectangle toPaint = getSize().intersection(r);
197 if (!isShowing() || toPaint.isEmpty()) {
198 return;
199 }
200 // First, post the PaintEvent for this peer
201 super.repaintPeer(toPaint);
202 // Second, handle all the children
203 // Use the straight order of children, so the bottom
204 // ones are painted first
205 repaintChildren(toPaint);
206 }
207
208 /**
209 * Paints all the child peers in the straight z-order, so the
210 * bottom-most ones are painted first.
211 */
212 private void repaintChildren(final Rectangle r) {
213 final Rectangle content = getContentSize();
214 for (final LWComponentPeer<?, ?> child : getChildren()) {
215 final Rectangle childBounds = child.getBounds();
216 Rectangle toPaint = r.intersection(childBounds);
217 toPaint = toPaint.intersection(content);
218 toPaint.translate(-childBounds.x, -childBounds.y);
219 child.repaintPeer(toPaint);
220 }
221 }
222
223 Rectangle getContentSize() {
224 return getSize();
225 }
226
227 @Override
228 public void setEnabled(final boolean e) {
229 super.setEnabled(e);
230 for (final LWComponentPeer<?, ?> child : getChildren()) {
231 child.setEnabled(e && child.getTarget().isEnabled());
232 }
233 }
234
235 @Override
236 public void setBackground(final Color c) {
237 for (final LWComponentPeer<?, ?> child : getChildren()) {
238 if (!child.getTarget().isBackgroundSet()) {
239 child.setBackground(c);
240 }
241 }
242 super.setBackground(c);
243 }
244
245 @Override
246 public void setForeground(final Color c) {
247 for (final LWComponentPeer<?, ?> child : getChildren()) {
248 if (!child.getTarget().isForegroundSet()) {
249 child.setForeground(c);
250 }
251 }
252 super.setForeground(c);
253 }
254
255 @Override
256 public void setFont(final Font f) {
257 for (final LWComponentPeer<?, ?> child : getChildren()) {
258 if (!child.getTarget().isFontSet()) {
259 child.setFont(f);
260 }
261 }
262 super.setFont(f);
263 }
264
265 @Override
266 public final void paint(final Graphics g) {
267 super.paint(g);
268 SunGraphicsCallback.PaintHeavyweightComponentsCallback.getInstance()
269 .runComponents(getTarget().getComponents(), g,
270 SunGraphicsCallback.LIGHTWEIGHTS
271 | SunGraphicsCallback.HEAVYWEIGHTS);
272 }
273
274 @Override
275 public final void print(final Graphics g) {
276 super.print(g);
277 SunGraphicsCallback.PrintHeavyweightComponentsCallback.getInstance()
|