author | yan |
Mon, 06 Oct 2008 16:45:00 +0400 | |
changeset 1966 | 12a51fb0db0d |
parent 449 | 7820f232278d |
child 2453 | 35e5fab82613 |
permissions | -rw-r--r-- |
2 | 1 |
/* |
107 | 2 |
* Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. |
2 | 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. Sun designates this |
|
8 |
* particular file as subject to the "Classpath" exception as provided |
|
9 |
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
|
22 |
* CA 95054 USA or visit www.sun.com if you need additional information or |
|
23 |
* have any questions. |
|
24 |
*/ |
|
25 |
package sun.awt.X11; |
|
26 |
||
107 | 27 |
import java.awt.Color; |
28 |
import java.awt.Dimension; |
|
29 |
import java.awt.Font; |
|
30 |
import java.awt.FontMetrics; |
|
31 |
import java.awt.Frame; |
|
32 |
import java.awt.Graphics; |
|
33 |
import java.awt.Insets; |
|
34 |
import java.awt.MenuBar; |
|
35 |
import java.awt.Rectangle; |
|
36 |
import java.awt.peer.FramePeer; |
|
37 |
import java.util.logging.Level; |
|
38 |
import java.util.logging.Logger; |
|
2 | 39 |
|
439
3488710b02f8
6623459: Get rid of XConstant, XProtocolConstants and XUtilConstants antipattern
dav
parents:
129
diff
changeset
|
40 |
class XFramePeer extends XDecoratedPeer implements FramePeer { |
2 | 41 |
private static Logger log = Logger.getLogger("sun.awt.X11.XFramePeer"); |
42 |
private static Logger stateLog = Logger.getLogger("sun.awt.X11.states"); |
|
43 |
private static Logger insLog = Logger.getLogger("sun.awt.X11.insets.XFramePeer"); |
|
44 |
||
45 |
XMenuBarPeer menubarPeer; |
|
46 |
MenuBar menubar; |
|
47 |
int state; |
|
48 |
private Boolean undecorated; |
|
49 |
||
50 |
private static final int MENUBAR_HEIGHT_IF_NO_MENUBAR = 0; |
|
51 |
private int lastAppliedMenubarHeight = MENUBAR_HEIGHT_IF_NO_MENUBAR; |
|
52 |
||
53 |
XFramePeer(Frame target) { |
|
54 |
super(target); |
|
55 |
} |
|
56 |
||
57 |
XFramePeer(XCreateWindowParams params) { |
|
58 |
super(params); |
|
59 |
} |
|
60 |
||
61 |
void preInit(XCreateWindowParams params) { |
|
62 |
super.preInit(params); |
|
63 |
Frame target = (Frame)(this.target); |
|
64 |
// set the window attributes for this Frame |
|
65 |
winAttr.initialState = target.getExtendedState(); |
|
66 |
state = 0; |
|
67 |
undecorated = Boolean.valueOf(target.isUndecorated()); |
|
68 |
winAttr.nativeDecor = !target.isUndecorated(); |
|
69 |
if (winAttr.nativeDecor) { |
|
70 |
winAttr.decorations = winAttr.AWT_DECOR_ALL; |
|
71 |
} else { |
|
72 |
winAttr.decorations = winAttr.AWT_DECOR_NONE; |
|
73 |
} |
|
439
3488710b02f8
6623459: Get rid of XConstant, XProtocolConstants and XUtilConstants antipattern
dav
parents:
129
diff
changeset
|
74 |
winAttr.functions = MWMConstants.MWM_FUNC_ALL; |
2 | 75 |
winAttr.isResizable = true; // target.isResizable(); |
76 |
winAttr.title = target.getTitle(); |
|
77 |
winAttr.initialResizability = target.isResizable(); |
|
78 |
if (log.isLoggable(Level.FINE)) { |
|
79 |
log.log(Level.FINE, "Frame''s initial attributes: decor {0}, resizable {1}, undecorated {2}, initial state {3}", |
|
80 |
new Object[] {Integer.valueOf(winAttr.decorations), Boolean.valueOf(winAttr.initialResizability), |
|
81 |
Boolean.valueOf(!winAttr.nativeDecor), Integer.valueOf(winAttr.initialState)}); |
|
82 |
} |
|
83 |
} |
|
84 |
||
85 |
void postInit(XCreateWindowParams params) { |
|
86 |
super.postInit(params); |
|
87 |
setupState(true); |
|
88 |
} |
|
89 |
||
129
f995b9c9c5fa
6589527: Window and Frame instances can hide their "Applet Warning"
anthony
parents:
107
diff
changeset
|
90 |
@Override |
f995b9c9c5fa
6589527: Window and Frame instances can hide their "Applet Warning"
anthony
parents:
107
diff
changeset
|
91 |
boolean isTargetUndecorated() { |
2 | 92 |
if (undecorated != null) { |
93 |
return undecorated.booleanValue(); |
|
94 |
} else { |
|
95 |
return ((Frame)target).isUndecorated(); |
|
96 |
} |
|
97 |
} |
|
98 |
||
99 |
void setupState(boolean onInit) { |
|
100 |
if (onInit) { |
|
101 |
state = winAttr.initialState; |
|
102 |
} |
|
103 |
if ((state & Frame.ICONIFIED) != 0) { |
|
439
3488710b02f8
6623459: Get rid of XConstant, XProtocolConstants and XUtilConstants antipattern
dav
parents:
129
diff
changeset
|
104 |
setInitialState(XUtilConstants.IconicState); |
2 | 105 |
} else { |
439
3488710b02f8
6623459: Get rid of XConstant, XProtocolConstants and XUtilConstants antipattern
dav
parents:
129
diff
changeset
|
106 |
setInitialState(XUtilConstants.NormalState); |
2 | 107 |
} |
108 |
setExtendedState(state); |
|
109 |
} |
|
110 |
||
111 |
public void setMenuBar(MenuBar mb) { |
|
112 |
// state_lock should always be the second after awt_lock |
|
113 |
XToolkit.awtLock(); |
|
114 |
try { |
|
115 |
synchronized(getStateLock()) { |
|
116 |
if (mb == menubar) return; |
|
117 |
if (mb == null) { |
|
118 |
if (menubar != null) { |
|
119 |
menubarPeer.xSetVisible(false); |
|
120 |
menubar = null; |
|
121 |
menubarPeer.dispose(); |
|
122 |
menubarPeer = null; |
|
123 |
} |
|
124 |
} else { |
|
125 |
menubar = mb; |
|
126 |
menubarPeer = (XMenuBarPeer) mb.getPeer(); |
|
127 |
if (menubarPeer != null) { |
|
128 |
menubarPeer.init((Frame)target); |
|
129 |
} |
|
130 |
} |
|
131 |
} |
|
132 |
} finally { |
|
133 |
XToolkit.awtUnlock(); |
|
134 |
} |
|
135 |
||
136 |
reshapeMenubarPeer(); |
|
137 |
} |
|
138 |
||
139 |
XMenuBarPeer getMenubarPeer() { |
|
140 |
return menubarPeer; |
|
141 |
} |
|
142 |
||
143 |
int getMenuBarHeight() { |
|
144 |
if (menubarPeer != null) { |
|
145 |
return menubarPeer.getDesiredHeight(); |
|
146 |
} else { |
|
147 |
return MENUBAR_HEIGHT_IF_NO_MENUBAR; |
|
148 |
} |
|
149 |
} |
|
150 |
||
151 |
void updateChildrenSizes() { |
|
152 |
super.updateChildrenSizes(); |
|
153 |
// XWindow.reshape calls XBaseWindow.xSetBounds, which acquires |
|
154 |
// the AWT lock, so we have to acquire the AWT lock here |
|
155 |
// before getStateLock() to avoid a deadlock with the Toolkit thread |
|
156 |
// when this method is called on the EDT. |
|
157 |
XToolkit.awtLock(); |
|
158 |
try { |
|
159 |
synchronized(getStateLock()) { |
|
160 |
int width = dimensions.getClientSize().width; |
|
161 |
if (menubarPeer != null) { |
|
162 |
menubarPeer.reshape(0, 0, width, getMenuBarHeight()); |
|
163 |
} |
|
164 |
} |
|
165 |
} finally { |
|
166 |
XToolkit.awtUnlock(); |
|
167 |
} |
|
168 |
} |
|
169 |
||
170 |
/** |
|
171 |
* In addition to reshaping menubarPeer (by using 'updateChildrenSizes') |
|
172 |
* this method also performs some frame reaction on this (i.e. layouts |
|
173 |
* other frame children, if required) |
|
174 |
*/ |
|
175 |
final void reshapeMenubarPeer() { |
|
176 |
XToolkit.executeOnEventHandlerThread( |
|
177 |
target, |
|
178 |
new Runnable() { |
|
179 |
public void run() { |
|
180 |
updateChildrenSizes(); |
|
181 |
boolean heightChanged = false; |
|
182 |
||
183 |
int height = getMenuBarHeight(); |
|
184 |
// Neither 'XToolkit.awtLock()' nor 'getStateLock()' |
|
185 |
// is acquired under this call, and it looks to run |
|
186 |
// thread-safely. I currently see no reason to move |
|
187 |
// it under following 'synchronized' clause. |
|
188 |
||
189 |
synchronized(getStateLock()) { |
|
190 |
if (height != lastAppliedMenubarHeight) { |
|
191 |
lastAppliedMenubarHeight = height; |
|
192 |
heightChanged = true; |
|
193 |
} |
|
194 |
} |
|
195 |
if (heightChanged) { |
|
196 |
// To make frame contents be re-layout (copied from |
|
197 |
// 'XDecoratedPeer.revalidate()'). These are not |
|
198 |
// 'synchronized', because can recursively call client |
|
199 |
// methods, which are not supposed to be called with locks |
|
200 |
// acquired. |
|
201 |
target.invalidate(); |
|
202 |
target.validate(); |
|
203 |
} |
|
204 |
} |
|
205 |
} |
|
206 |
); |
|
207 |
} |
|
208 |
||
209 |
public void setMaximizedBounds(Rectangle b) { |
|
210 |
if (insLog.isLoggable(Level.FINE)) insLog.fine("Setting maximized bounds to " + b); |
|
211 |
if (b == null) return; |
|
212 |
maxBounds = new Rectangle(b); |
|
213 |
XToolkit.awtLock(); |
|
214 |
try { |
|
215 |
XSizeHints hints = getHints(); |
|
439
3488710b02f8
6623459: Get rid of XConstant, XProtocolConstants and XUtilConstants antipattern
dav
parents:
129
diff
changeset
|
216 |
hints.set_flags(hints.get_flags() | (int)XUtilConstants.PMaxSize); |
2 | 217 |
if (b.width != Integer.MAX_VALUE) { |
218 |
hints.set_max_width(b.width); |
|
219 |
} else { |
|
220 |
hints.set_max_width((int)XlibWrapper.DisplayWidth(XToolkit.getDisplay(), XlibWrapper.DefaultScreen(XToolkit.getDisplay()))); |
|
221 |
} |
|
222 |
if (b.height != Integer.MAX_VALUE) { |
|
223 |
hints.set_max_height(b.height); |
|
224 |
} else { |
|
225 |
hints.set_max_height((int)XlibWrapper.DisplayHeight(XToolkit.getDisplay(), XlibWrapper.DefaultScreen(XToolkit.getDisplay()))); |
|
226 |
} |
|
227 |
if (insLog.isLoggable(Level.FINER)) insLog.finer("Setting hints, flags " + XlibWrapper.hintsToString(hints.get_flags())); |
|
228 |
XlibWrapper.XSetWMNormalHints(XToolkit.getDisplay(), window, hints.pData); |
|
229 |
} finally { |
|
230 |
XToolkit.awtUnlock(); |
|
231 |
} |
|
232 |
} |
|
233 |
||
234 |
public int getState() { return state; } |
|
235 |
||
236 |
public void setState(int newState) { |
|
237 |
if (!isShowing()) { |
|
238 |
stateLog.finer("Frame is not showing"); |
|
239 |
state = newState; |
|
240 |
return; |
|
241 |
} |
|
242 |
changeState(newState); |
|
243 |
} |
|
244 |
||
245 |
void changeState(int newState) { |
|
246 |
int changed = state ^ newState; |
|
247 |
int changeIconic = changed & Frame.ICONIFIED; |
|
248 |
boolean iconic = (newState & Frame.ICONIFIED) != 0; |
|
249 |
stateLog.log(Level.FINER, "Changing state, old state {0}, new state {1}(iconic {2})", |
|
250 |
new Object[] {Integer.valueOf(state), Integer.valueOf(newState), Boolean.valueOf(iconic)}); |
|
251 |
if (changeIconic != 0 && iconic) { |
|
252 |
if (stateLog.isLoggable(Level.FINER)) stateLog.finer("Iconifying shell " + getShell() + ", this " + this + ", screen " + getScreenNumber()); |
|
253 |
XToolkit.awtLock(); |
|
254 |
try { |
|
255 |
int res = XlibWrapper.XIconifyWindow(XToolkit.getDisplay(), getShell(), getScreenNumber()); |
|
256 |
if (stateLog.isLoggable(Level.FINER)) stateLog.finer("XIconifyWindow returned " + res); |
|
257 |
} |
|
258 |
finally { |
|
259 |
XToolkit.awtUnlock(); |
|
260 |
} |
|
261 |
} |
|
262 |
if ((changed & ~Frame.ICONIFIED) != 0) { |
|
263 |
setExtendedState(newState); |
|
264 |
} |
|
265 |
if (changeIconic != 0 && !iconic) { |
|
266 |
if (stateLog.isLoggable(Level.FINER)) stateLog.finer("DeIconifying " + this); |
|
267 |
xSetVisible(true); |
|
268 |
} |
|
269 |
} |
|
270 |
||
271 |
void setExtendedState(int newState) { |
|
272 |
XWM.getWM().setExtendedState(this, newState); |
|
273 |
} |
|
274 |
||
275 |
public void handlePropertyNotify(XEvent xev) { |
|
276 |
super.handlePropertyNotify(xev); |
|
277 |
XPropertyEvent ev = xev.get_xproperty(); |
|
278 |
||
279 |
log.log(Level.FINER, "Property change {0}", new Object[] {ev}); |
|
280 |
/* |
|
281 |
* Let's see if this is a window state protocol message, and |
|
282 |
* if it is - decode a new state in terms of java constants. |
|
283 |
*/ |
|
107 | 284 |
if (!XWM.getWM().isStateChange(this, ev)) { |
285 |
stateLog.finer("either not a state atom or state has not been changed"); |
|
2 | 286 |
return; |
287 |
} |
|
288 |
||
107 | 289 |
final int newState = XWM.getWM().getState(this); |
290 |
int changed = state ^ newState; |
|
2 | 291 |
if (changed == 0) { |
292 |
stateLog.finer("State is the same: " + state); |
|
293 |
return; |
|
294 |
} |
|
295 |
||
296 |
int old_state = state; |
|
107 | 297 |
state = newState; |
2 | 298 |
|
299 |
if ((changed & Frame.ICONIFIED) != 0) { |
|
300 |
if ((state & Frame.ICONIFIED) != 0) { |
|
301 |
stateLog.finer("Iconified"); |
|
302 |
handleIconify(); |
|
303 |
} else { |
|
304 |
stateLog.finer("DeIconified"); |
|
305 |
content.purgeIconifiedExposeEvents(); |
|
306 |
handleDeiconify(); |
|
307 |
} |
|
308 |
} |
|
309 |
handleStateChange(old_state, state); |
|
310 |
} |
|
311 |
||
312 |
// NOTE: This method may be called by privileged threads. |
|
313 |
// DO NOT INVOKE CLIENT CODE ON THIS THREAD! |
|
314 |
public void handleStateChange(int oldState, int newState) { |
|
315 |
super.handleStateChange(oldState, newState); |
|
316 |
for (ToplevelStateListener topLevelListenerTmp : toplevelStateListeners) { |
|
317 |
topLevelListenerTmp.stateChangedJava(oldState, newState); |
|
318 |
} |
|
319 |
} |
|
320 |
||
321 |
public void setVisible(boolean vis) { |
|
322 |
if (vis) { |
|
323 |
setupState(false); |
|
324 |
} else { |
|
325 |
if ((state & Frame.MAXIMIZED_BOTH) != 0) { |
|
326 |
XWM.getWM().setExtendedState(this, state & ~Frame.MAXIMIZED_BOTH); |
|
327 |
} |
|
328 |
} |
|
329 |
super.setVisible(vis); |
|
330 |
if (vis && maxBounds != null) { |
|
331 |
setMaximizedBounds(maxBounds); |
|
332 |
} |
|
333 |
} |
|
334 |
||
335 |
void setInitialState(int wm_state) { |
|
336 |
XToolkit.awtLock(); |
|
337 |
try { |
|
338 |
XWMHints hints = getWMHints(); |
|
439
3488710b02f8
6623459: Get rid of XConstant, XProtocolConstants and XUtilConstants antipattern
dav
parents:
129
diff
changeset
|
339 |
hints.set_flags((int)XUtilConstants.StateHint | hints.get_flags()); |
2 | 340 |
hints.set_initial_state(wm_state); |
341 |
if (stateLog.isLoggable(Level.FINE)) stateLog.fine("Setting initial WM state on " + this + " to " + wm_state); |
|
342 |
XlibWrapper.XSetWMHints(XToolkit.getDisplay(), getWindow(), hints.pData); |
|
343 |
} |
|
344 |
finally { |
|
345 |
XToolkit.awtUnlock(); |
|
346 |
} |
|
347 |
} |
|
348 |
||
349 |
public void dispose() { |
|
350 |
if (menubarPeer != null) { |
|
351 |
menubarPeer.dispose(); |
|
352 |
} |
|
353 |
super.dispose(); |
|
354 |
} |
|
355 |
||
356 |
boolean isMaximized() { |
|
357 |
return (state & (Frame.MAXIMIZED_VERT | Frame.MAXIMIZED_HORIZ)) != 0; |
|
358 |
} |
|
359 |
||
360 |
||
361 |
||
362 |
||
363 |
static final int CROSSHAIR_INSET = 5; |
|
364 |
||
365 |
static final int BUTTON_Y = CROSSHAIR_INSET + 1; |
|
366 |
static final int BUTTON_W = 17; |
|
367 |
static final int BUTTON_H = 17; |
|
368 |
||
369 |
static final int SYS_MENU_X = CROSSHAIR_INSET + 1; |
|
370 |
static final int SYS_MENU_CONTAINED_X = SYS_MENU_X + 5; |
|
371 |
static final int SYS_MENU_CONTAINED_Y = BUTTON_Y + 7; |
|
372 |
static final int SYS_MENU_CONTAINED_W = 8; |
|
373 |
static final int SYS_MENU_CONTAINED_H = 3; |
|
374 |
||
375 |
static final int MAXIMIZE_X_DIFF = CROSSHAIR_INSET + BUTTON_W; |
|
376 |
static final int MAXIMIZE_CONTAINED_X_DIFF = MAXIMIZE_X_DIFF - 5; |
|
377 |
static final int MAXIMIZE_CONTAINED_Y = BUTTON_Y + 5; |
|
378 |
static final int MAXIMIZE_CONTAINED_W = 8; |
|
379 |
static final int MAXIMIZE_CONTAINED_H = 8; |
|
380 |
||
381 |
static final int MINIMIZE_X_DIFF = MAXIMIZE_X_DIFF + BUTTON_W; |
|
382 |
static final int MINIMIZE_CONTAINED_X_DIFF = MINIMIZE_X_DIFF - 7; |
|
383 |
static final int MINIMIZE_CONTAINED_Y = BUTTON_Y + 7; |
|
384 |
static final int MINIMIZE_CONTAINED_W = 3; |
|
385 |
static final int MINIMIZE_CONTAINED_H = 3; |
|
386 |
||
387 |
static final int TITLE_X = SYS_MENU_X + BUTTON_W; |
|
388 |
static final int TITLE_W_DIFF = BUTTON_W * 3 + CROSSHAIR_INSET * 2 - 1; |
|
389 |
static final int TITLE_MID_Y = BUTTON_Y + (BUTTON_H / 2); |
|
390 |
||
391 |
static final int MENUBAR_X = CROSSHAIR_INSET + 1; |
|
392 |
static final int MENUBAR_Y = BUTTON_Y + BUTTON_H; |
|
393 |
||
394 |
static final int HORIZ_RESIZE_INSET = CROSSHAIR_INSET + BUTTON_H; |
|
395 |
static final int VERT_RESIZE_INSET = CROSSHAIR_INSET + BUTTON_W; |
|
396 |
||
397 |
||
398 |
/* |
|
399 |
* Print the native component by rendering the Motif look ourselves. |
|
400 |
* We also explicitly print the MenuBar since a MenuBar isn't a subclass |
|
401 |
* of Component (and thus it has no "print" method which gets called by |
|
402 |
* default). |
|
403 |
*/ |
|
404 |
public void print(Graphics g) { |
|
405 |
super.print(g); |
|
406 |
||
407 |
Frame f = (Frame)target; |
|
408 |
Insets finsets = f.getInsets(); |
|
409 |
Dimension fsize = f.getSize(); |
|
410 |
||
411 |
Color bg = f.getBackground(); |
|
412 |
Color fg = f.getForeground(); |
|
413 |
Color highlight = bg.brighter(); |
|
414 |
Color shadow = bg.darker(); |
|
415 |
||
416 |
// Well, we could query for the currently running window manager |
|
417 |
// and base the look on that, or we could just always do dtwm. |
|
418 |
// aim, tball, and levenson all agree we'll just do dtwm. |
|
419 |
||
420 |
if (hasDecorations(XWindowAttributesData.AWT_DECOR_BORDER)) { |
|
421 |
||
422 |
// top outer -- because we'll most likely be drawing on white paper, |
|
423 |
// for aesthetic reasons, don't make any part of the outer border |
|
424 |
// pure white |
|
425 |
if (highlight.equals(Color.white)) { |
|
426 |
g.setColor(new Color(230, 230, 230)); |
|
427 |
} |
|
428 |
else { |
|
429 |
g.setColor(highlight); |
|
430 |
} |
|
431 |
g.drawLine(0, 0, fsize.width, 0); |
|
432 |
g.drawLine(0, 1, fsize.width - 1, 1); |
|
433 |
||
434 |
// left outer |
|
435 |
// if (highlight.equals(Color.white)) { |
|
436 |
// g.setColor(new Color(230, 230, 230)); |
|
437 |
// } |
|
438 |
// else { |
|
439 |
// g.setColor(highlight); |
|
440 |
// } |
|
441 |
g.drawLine(0, 0, 0, fsize.height); |
|
442 |
g.drawLine(1, 0, 1, fsize.height - 1); |
|
443 |
||
444 |
// bottom cross-hair |
|
445 |
g.setColor(highlight); |
|
446 |
g.drawLine(CROSSHAIR_INSET + 1, fsize.height - CROSSHAIR_INSET, |
|
447 |
fsize.width - CROSSHAIR_INSET, |
|
448 |
fsize.height - CROSSHAIR_INSET); |
|
449 |
||
450 |
// right cross-hair |
|
451 |
// g.setColor(highlight); |
|
452 |
g.drawLine(fsize.width - CROSSHAIR_INSET, CROSSHAIR_INSET + 1, |
|
453 |
fsize.width - CROSSHAIR_INSET, |
|
454 |
fsize.height - CROSSHAIR_INSET); |
|
455 |
||
456 |
// bottom outer |
|
457 |
g.setColor(shadow); |
|
458 |
g.drawLine(1, fsize.height, fsize.width, fsize.height); |
|
459 |
g.drawLine(2, fsize.height - 1, fsize.width, fsize.height - 1); |
|
460 |
||
461 |
// right outer |
|
462 |
// g.setColor(shadow); |
|
463 |
g.drawLine(fsize.width, 1, fsize.width, fsize.height); |
|
464 |
g.drawLine(fsize.width - 1, 2, fsize.width - 1, fsize.height); |
|
465 |
||
466 |
// top cross-hair |
|
467 |
// g.setColor(shadow); |
|
468 |
g.drawLine(CROSSHAIR_INSET, CROSSHAIR_INSET, |
|
469 |
fsize.width - CROSSHAIR_INSET, CROSSHAIR_INSET); |
|
470 |
||
471 |
// left cross-hair |
|
472 |
// g.setColor(shadow); |
|
473 |
g.drawLine(CROSSHAIR_INSET, CROSSHAIR_INSET, CROSSHAIR_INSET, |
|
474 |
fsize.height - CROSSHAIR_INSET); |
|
475 |
} |
|
476 |
||
477 |
if (hasDecorations(XWindowAttributesData.AWT_DECOR_TITLE)) { |
|
478 |
||
479 |
if (hasDecorations(XWindowAttributesData.AWT_DECOR_MENU)) { |
|
480 |
||
481 |
// system menu |
|
482 |
g.setColor(bg); |
|
483 |
g.fill3DRect(SYS_MENU_X, BUTTON_Y, BUTTON_W, BUTTON_H, true); |
|
484 |
g.fill3DRect(SYS_MENU_CONTAINED_X, SYS_MENU_CONTAINED_Y, |
|
485 |
SYS_MENU_CONTAINED_W, SYS_MENU_CONTAINED_H, true); |
|
486 |
} |
|
487 |
||
488 |
// title bar |
|
489 |
// g.setColor(bg); |
|
490 |
g.fill3DRect(TITLE_X, BUTTON_Y, fsize.width - TITLE_W_DIFF, BUTTON_H, |
|
491 |
true); |
|
492 |
||
493 |
if (hasDecorations(XWindowAttributesData.AWT_DECOR_MINIMIZE)) { |
|
494 |
||
495 |
// minimize button |
|
496 |
// g.setColor(bg); |
|
497 |
g.fill3DRect(fsize.width - MINIMIZE_X_DIFF, BUTTON_Y, BUTTON_W, |
|
498 |
BUTTON_H, true); |
|
499 |
g.fill3DRect(fsize.width - MINIMIZE_CONTAINED_X_DIFF, |
|
500 |
MINIMIZE_CONTAINED_Y, MINIMIZE_CONTAINED_W, |
|
501 |
MINIMIZE_CONTAINED_H, true); |
|
502 |
} |
|
503 |
||
504 |
if (hasDecorations(XWindowAttributesData.AWT_DECOR_MAXIMIZE)) { |
|
505 |
||
506 |
// maximize button |
|
507 |
// g.setColor(bg); |
|
508 |
g.fill3DRect(fsize.width - MAXIMIZE_X_DIFF, BUTTON_Y, BUTTON_W, |
|
509 |
BUTTON_H, true); |
|
510 |
g.fill3DRect(fsize.width - MAXIMIZE_CONTAINED_X_DIFF, |
|
511 |
MAXIMIZE_CONTAINED_Y, MAXIMIZE_CONTAINED_W, |
|
512 |
MAXIMIZE_CONTAINED_H, true); |
|
513 |
} |
|
514 |
||
515 |
// title bar text |
|
516 |
g.setColor(fg); |
|
517 |
Font sysfont = new Font(Font.SANS_SERIF, Font.PLAIN, 10); |
|
518 |
g.setFont(sysfont); |
|
519 |
FontMetrics sysfm = g.getFontMetrics(); |
|
520 |
String ftitle = f.getTitle(); |
|
521 |
g.drawString(ftitle, |
|
522 |
((TITLE_X + TITLE_X + fsize.width - TITLE_W_DIFF) / 2) - |
|
523 |
(sysfm.stringWidth(ftitle) / 2), |
|
524 |
TITLE_MID_Y + sysfm.getMaxDescent()); |
|
525 |
} |
|
526 |
||
527 |
if (f.isResizable() && |
|
528 |
hasDecorations(XWindowAttributesData.AWT_DECOR_RESIZEH)) { |
|
529 |
||
530 |
// add resize cross hairs |
|
531 |
||
532 |
// upper-left horiz (shadow) |
|
533 |
g.setColor(shadow); |
|
534 |
g.drawLine(1, HORIZ_RESIZE_INSET, CROSSHAIR_INSET, |
|
535 |
HORIZ_RESIZE_INSET); |
|
536 |
// upper-left vert (shadow) |
|
537 |
// g.setColor(shadow); |
|
538 |
g.drawLine(VERT_RESIZE_INSET, 1, VERT_RESIZE_INSET, CROSSHAIR_INSET); |
|
539 |
// upper-right horiz (shadow) |
|
540 |
// g.setColor(shadow); |
|
541 |
g.drawLine(fsize.width - CROSSHAIR_INSET + 1, HORIZ_RESIZE_INSET, |
|
542 |
fsize.width, HORIZ_RESIZE_INSET); |
|
543 |
// upper-right vert (shadow) |
|
544 |
// g.setColor(shadow); |
|
545 |
g.drawLine(fsize.width - VERT_RESIZE_INSET - 1, 2, |
|
546 |
fsize.width - VERT_RESIZE_INSET - 1, CROSSHAIR_INSET + 1); |
|
547 |
// lower-left horiz (shadow) |
|
548 |
// g.setColor(shadow); |
|
549 |
g.drawLine(1, fsize.height - HORIZ_RESIZE_INSET - 1, |
|
550 |
CROSSHAIR_INSET, fsize.height - HORIZ_RESIZE_INSET - 1); |
|
551 |
// lower-left vert (shadow) |
|
552 |
// g.setColor(shadow); |
|
553 |
g.drawLine(VERT_RESIZE_INSET, fsize.height - CROSSHAIR_INSET + 1, |
|
554 |
VERT_RESIZE_INSET, fsize.height); |
|
555 |
// lower-right horiz (shadow) |
|
556 |
// g.setColor(shadow); |
|
557 |
g.drawLine(fsize.width - CROSSHAIR_INSET + 1, |
|
558 |
fsize.height - HORIZ_RESIZE_INSET - 1, fsize.width, |
|
559 |
fsize.height - HORIZ_RESIZE_INSET - 1); |
|
560 |
// lower-right vert (shadow) |
|
561 |
// g.setColor(shadow); |
|
562 |
g.drawLine(fsize.width - VERT_RESIZE_INSET - 1, |
|
563 |
fsize.height - CROSSHAIR_INSET + 1, |
|
564 |
fsize.width - VERT_RESIZE_INSET - 1, fsize.height); |
|
565 |
||
566 |
// upper-left horiz (highlight) |
|
567 |
g.setColor(highlight); |
|
568 |
g.drawLine(2, HORIZ_RESIZE_INSET + 1, CROSSHAIR_INSET, |
|
569 |
HORIZ_RESIZE_INSET + 1); |
|
570 |
// upper-left vert (highlight) |
|
571 |
// g.setColor(highlight); |
|
572 |
g.drawLine(VERT_RESIZE_INSET + 1, 2, VERT_RESIZE_INSET + 1, |
|
573 |
CROSSHAIR_INSET); |
|
574 |
// upper-right horiz (highlight) |
|
575 |
// g.setColor(highlight); |
|
576 |
g.drawLine(fsize.width - CROSSHAIR_INSET + 1, |
|
577 |
HORIZ_RESIZE_INSET + 1, fsize.width - 1, |
|
578 |
HORIZ_RESIZE_INSET + 1); |
|
579 |
// upper-right vert (highlight) |
|
580 |
// g.setColor(highlight); |
|
581 |
g.drawLine(fsize.width - VERT_RESIZE_INSET, 2, |
|
582 |
fsize.width - VERT_RESIZE_INSET, CROSSHAIR_INSET); |
|
583 |
// lower-left horiz (highlight) |
|
584 |
// g.setColor(highlight); |
|
585 |
g.drawLine(2, fsize.height - HORIZ_RESIZE_INSET, CROSSHAIR_INSET, |
|
586 |
fsize.height - HORIZ_RESIZE_INSET); |
|
587 |
// lower-left vert (highlight) |
|
588 |
// g.setColor(highlight); |
|
589 |
g.drawLine(VERT_RESIZE_INSET + 1, |
|
590 |
fsize.height - CROSSHAIR_INSET + 1, |
|
591 |
VERT_RESIZE_INSET + 1, fsize.height - 1); |
|
592 |
// lower-right horiz (highlight) |
|
593 |
// g.setColor(highlight); |
|
594 |
g.drawLine(fsize.width - CROSSHAIR_INSET + 1, |
|
595 |
fsize.height - HORIZ_RESIZE_INSET, fsize.width - 1, |
|
596 |
fsize.height - HORIZ_RESIZE_INSET); |
|
597 |
// lower-right vert (highlight) |
|
598 |
// g.setColor(highlight); |
|
599 |
g.drawLine(fsize.width - VERT_RESIZE_INSET, |
|
600 |
fsize.height - CROSSHAIR_INSET + 1, |
|
601 |
fsize.width - VERT_RESIZE_INSET, fsize.height - 1); |
|
602 |
} |
|
603 |
||
604 |
XMenuBarPeer peer = menubarPeer; |
|
605 |
if (peer != null) { |
|
606 |
Insets insets = getInsets(); |
|
607 |
Graphics ng = g.create(); |
|
608 |
int menubarX = 0; |
|
609 |
int menubarY = 0; |
|
610 |
if (hasDecorations(XWindowAttributesData.AWT_DECOR_BORDER)) { |
|
611 |
menubarX += CROSSHAIR_INSET + 1; |
|
612 |
menubarY += CROSSHAIR_INSET + 1; |
|
613 |
} |
|
614 |
if (hasDecorations(XWindowAttributesData.AWT_DECOR_TITLE)) { |
|
615 |
menubarY += BUTTON_H; |
|
616 |
} |
|
617 |
try { |
|
618 |
ng.translate(menubarX, menubarY); |
|
619 |
peer.print(ng); |
|
620 |
} finally { |
|
621 |
ng.dispose(); |
|
622 |
} |
|
623 |
} |
|
624 |
} |
|
625 |
||
626 |
public void setBoundsPrivate(int x, int y, int width, int height) { |
|
627 |
setBounds(x, y, width, height, SET_BOUNDS); |
|
628 |
} |
|
629 |
||
630 |
public Rectangle getBoundsPrivate() { |
|
631 |
return getBounds(); |
|
632 |
} |
|
633 |
} |