1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * ident "%Z%%M% %I% %E% SMI" 24 * 25 * Copyright (c) 2000 by Sun Microsystems, Inc. 26 * All rights reserved. 27 */ 28 29 /* 30 * Copyright (C) 1996 Active Software, Inc. 31 * All rights reserved. 32 * 33 * @(#) RootFrame.java 1.50 - last change made 07/25/97 34 */ 35 36 package sunsoft.jws.visual.rt.awt; 37 38 import sunsoft.jws.visual.rt.base.DesignerAccess; 39 import sunsoft.jws.visual.rt.base.*; 40 41 import java.awt.*; 42 43 public class RootFrame extends Frame implements RootWindow { 44 45 private Point location = new Point(0, 0); 46 47 private boolean skipValidate = false; 48 49 /* BEGIN JSTYLED */ 50 // 51 // The ignoreShow and ignoreHide flags are used as part of a workaround 52 // for an AWT problem with iconify and deiconify events. An infinite 53 // loop can happen under certain circumstances without this workaround. 54 // 55 // When hide is called on a window that is currently showing, AWT will 56 // deliver a WINDOW_ICONIFY event. Similarly, when show is called on a 57 // window that is currently hidden, AWT will deliver a WINDOW_DEICONIFY 58 // event. (Note that in JDK1.0.2, iconify events are not delivered with 59 // Windows95, but they are delivered with Motif). 60 // 61 // Now say that you have a callback for WINDOW_ICONIFY that hides 62 // the window, and a callback for WINDOW_DEICONIFY that shows the 63 // window. Normally this is ok because calling hide on a hidden window 64 // will not cause an iconify event to be delivered, and calling show 65 // on a mapped window will not cause a deiconify event to be delivered. 66 // 67 // But if the user iconifies and deiconifies a window while the 68 // application is busy, then a WINDOW_ICONIFY event and a 69 // WINDOW_DEICONIFY event will both be in the event queue at the same 70 // time. When the WINDOW_ICONIFY event is then handled, calling hide 71 // on the window will cause another WINDOW_ICONIFY event to be delivered 72 // because the window is currently showing. Then, when the 73 // WINDOW_DEICONIFY is handled, show will be called causing another 74 // WINDOW_DEICONIFY event to be delivered. You then go into an infinite 75 // loop with the window mapping and unmapping itself. 76 // 77 // The solution is to never allow hide to be called in the callback 78 // from a WINDOW_ICONIFY event, and never allow show to be called 79 // in the callback from a WINDOW_DEICONIFY event. 80 // 81 /* END JSTYLED */ 82 private boolean ignoreShow = false; 83 private boolean ignoreHide = false; 84 85 // Give windows a nice looking border. 86 static { 87 if (Global.isWindows95()) GBLayout.setWindowInsets(new Insets(1, 1, 1, 1))88 GBLayout.setWindowInsets(new Insets(1, 1, 1, 1)); 89 else if (Global.isWindowsNT()) GBLayout.setWindowInsets(new Insets(2, 3, 2, 3))90 GBLayout.setWindowInsets(new Insets(2, 3, 2, 3)); 91 else GBLayout.setWindowInsets(new Insets(4, 4, 4, 4))92 GBLayout.setWindowInsets(new Insets(4, 4, 4, 4)); 93 } 94 95 private RWHelper helper; 96 private Group subGroup; 97 RootFrame()98 public RootFrame() { 99 super(); 100 initHelper(); 101 } 102 RootFrame(String title)103 public RootFrame(String title) { 104 super(title); 105 initHelper(); 106 } 107 initHelper()108 private void initHelper() { 109 Class c = DesignerAccess.getRootWindowHelperClass(); 110 if (c != null) { 111 try { 112 helper = (RWHelper)c.newInstance(); 113 helper.setWindow(this); 114 } 115 catch (Exception ex) { 116 } 117 } 118 } 119 120 /** 121 * The subgroup is set on the bogus frames that are put around 122 * panel groups when the panel groups are running standalone. 123 * This situation only occurs when the generated main for a 124 * panel group is run from the command line. 125 */ setSubGroup(Group subGroup)126 public void setSubGroup(Group subGroup) { 127 this.subGroup = subGroup; 128 } 129 130 /** 131 * Returns the subgroup. The subgroup is non-null for frames 132 * that are used as wrappers for panel groups. 133 */ getSubGroup()134 public Group getSubGroup() { 135 return subGroup; 136 } 137 138 // Workaround for idiotic JDK1.1 bug where if you add a 139 // component to a container that it is already in, then 140 // the component will be removed from the container! 141 // 142 // #ifdef JDK1.1 addImpl(Component comp, Object constraints, int index)143 protected void addImpl(Component comp, Object constraints, 144 int index) { 145 if (comp.getParent() != this) 146 super.addImpl(comp, constraints, index); 147 } 148 // #endif 149 150 /** 151 * Workaround: Return the correct window location for Motif. 152 */ location()153 public Point location() { 154 if (Global.isMotif()) 155 return new Point(location.x, location.y); 156 else 157 return super.location(); 158 } 159 160 /** 161 * Update the location. 162 */ reshape(int x, int y, int w, int h)163 public void reshape(int x, int y, int w, int h) { 164 super.reshape(x, y, w, h); 165 location = new Point(x, y); 166 } 167 168 /** 169 * Event forwarding to groups. 170 * 171 * (see comment in GBPanel.java) 172 */ postEvent(Event evt)173 public boolean postEvent(Event evt) { 174 // See the comment at the top of the file 175 // for ignoreShow and ignoreHide 176 if (evt.id == Event.WINDOW_ICONIFY) 177 ignoreHide = true; 178 else if (evt.id == Event.WINDOW_DEICONIFY) 179 ignoreShow = true; 180 181 boolean marked = VJPanel.markEvent(evt, this); 182 boolean handled = super.postEvent(evt); 183 184 if (marked) 185 VJPanel.forwardEvent(evt, this); 186 187 // See the comment at the top of the file 188 // for ignoreShow and ignoreHide 189 if (evt.id == Event.WINDOW_ICONIFY) 190 ignoreHide = false; 191 else if (evt.id == Event.WINDOW_DEICONIFY) 192 ignoreShow = false; 193 194 return handled; 195 } 196 handleEvent(Event evt)197 public boolean handleEvent(Event evt) { 198 if (evt.id == Event.WINDOW_DESTROY) { 199 if (subGroup != null) { 200 subGroup.postMessage(new Message( 201 DesignerAccess.getContainer(subGroup), /* NOI18N */ 202 "AWT", evt, true)); 203 return true; 204 } 205 } else if (evt.target == this && evt.id == Event.WINDOW_MOVED) { 206 // The CDE window manager screws 207 // up the window location sometimes. 208 // The bug can be avoided by ignoring 209 // WINDOW_MOVED events that have 210 // the coordinates (0,0). 211 if (evt.x != 0 && evt.y != 0) 212 location = new Point(evt.x, evt.y); 213 } 214 215 return super.handleEvent(evt); 216 } 217 select()218 public void select() { 219 if (helper != null) 220 helper.select(); 221 } 222 unselect()223 public void unselect() { 224 if (helper != null) 225 helper.unselect(); 226 } 227 layoutMode()228 public void layoutMode() { 229 if (helper != null) 230 helper.layoutMode(); 231 } 232 previewMode()233 public void previewMode() { 234 if (helper != null) 235 helper.previewMode(); 236 } 237 previewSize()238 public Dimension previewSize() { 239 if (helper != null) 240 return helper.previewSize(); 241 else 242 return null; 243 } 244 addNotify()245 public void addNotify() { 246 if (helper != null) 247 helper.addNotify(); 248 super.addNotify(); 249 } 250 removeNotify()251 public void removeNotify() { 252 if (helper != null) 253 helper.removeNotify(); 254 super.removeNotify(); 255 } 256 layout()257 public void layout() { 258 if (helper != null) 259 helper.layout(); 260 super.layout(); 261 } 262 paint(Graphics g)263 public void paint(Graphics g) { 264 if (Global.isWindows()) 265 g = getGraphics(); 266 if (helper != null) 267 helper.paint(g); 268 super.paint(g); 269 } 270 mouseDown(Event evt, int x, int y)271 public boolean mouseDown(Event evt, int x, int y) { 272 if (helper != null) 273 return helper.mouseDown(evt, x, y); 274 return false; 275 } 276 show()277 public void show() { 278 // See the comment at the top of the file 279 // for ignoreShow and ignoreHide 280 if (ignoreShow) 281 return; 282 283 // 284 // Call show only if it is necessary. 285 // When the peer's show method 286 // is called, the peer will call validate 287 // back on the AWT component. 288 // 289 if (isShowing()) { 290 if (!Global.isWindows()) 291 toFront(); 292 return; 293 } 294 295 skipValidate = true; 296 super.show(); 297 skipValidate = false; 298 } 299 hide()300 public void hide() { 301 // See the comment at the top of the file 302 // for ignoreShow and ignoreHide 303 if (!ignoreHide) 304 super.hide(); 305 } 306 307 /** 308 * Don't do a validate during a show. 309 */ validate()310 public void validate() { 311 if (!skipValidate) 312 super.validate(); 313 } 314 315 /** 316 * Add some extra to the top inset if we are 317 * on Windows and the frame 318 * has a menubar. There is an AWT bug that 319 * causes the top insets to 320 * be too small when there is a menubar. 321 */ insets()322 public Insets insets() { 323 Insets insets = (Insets)super.insets().clone(); 324 if (Global.isWindows() && getMenuBar() != null && 325 insets.top < 30) 326 insets.top += 30; 327 return insets; 328 } 329 } 330