1 7 8 package org.gjt.jclasslib.mdi; 9 10 import javax.swing.*; 11 import javax.swing.event.InternalFrameEvent ; 12 import javax.swing.event.InternalFrameListener ; 13 import java.awt.*; 14 import java.awt.event.*; 15 import java.beans.*; 16 import java.util.*; 17 18 24 public class BasicDesktopManager extends DefaultDesktopManager 25 implements VetoableChangeListener, 26 InternalFrameListener 27 { 28 private static int NEW_INTERNAL_X_OFFSET = 22; 29 private static int NEW_INTERNAL_Y_OFFSET = 22; 30 private static int NEW_INTERNAL_WIDTH = 600; 31 private static int NEW_INTERNAL_HEIGHT = 400; 32 33 34 protected BasicMDIFrame parentFrame; 35 36 private int newInternalX = 0; 37 private int newInternalY = 0; 38 39 private JDesktopPane desktopPane; 40 private HashMap frameToMenuItem = new HashMap(); 41 private BasicInternalFrame activeFrame; 42 private LinkedList openFrames = new LinkedList(); 43 private int rollover = 0; 44 private int separatorMenuIndex = -1; 45 46 private boolean maximizationInProgress; 47 private boolean anyFrameMaximized; 48 49 53 public BasicDesktopManager(BasicMDIFrame parentFrame) { 54 this.parentFrame = parentFrame; 55 desktopPane = parentFrame.desktopPane; 56 } 57 58 62 public BasicMDIFrame getParentFrame() { 63 return parentFrame; 64 } 65 66 70 public JDesktopPane getDesktopPane() { 71 return desktopPane; 72 } 73 74 78 public java.util.List getOpenFrames() { 79 return openFrames; 80 } 81 82 86 public Rectangle getNextInternalFrameBounds() { 87 88 if (newInternalY + NEW_INTERNAL_HEIGHT > desktopPane.getHeight()) { 89 rollover++; 90 newInternalY = 0; 91 newInternalX = rollover * NEW_INTERNAL_X_OFFSET; 92 } 93 94 Rectangle nextBounds = new Rectangle(newInternalX, 95 newInternalY, 96 NEW_INTERNAL_WIDTH, 97 NEW_INTERNAL_HEIGHT); 98 99 newInternalX += NEW_INTERNAL_X_OFFSET; 100 newInternalY += NEW_INTERNAL_Y_OFFSET; 101 102 return nextBounds; 103 } 104 105 109 public void setActiveFrame(BasicInternalFrame activeFrame) { 110 this.activeFrame = activeFrame; 111 } 112 113 118 public BasicInternalFrame getOpenFrame(Object initParam) { 119 120 Iterator it = openFrames.iterator(); 121 while (it.hasNext()) { 122 BasicInternalFrame frame = (BasicInternalFrame)it.next(); 123 if (frame.getInitParam().equals(initParam)) { 124 return frame; 125 } 126 } 127 return null; 128 } 129 130 133 public void showAll() { 134 Iterator it = openFrames.iterator(); 135 while (it.hasNext()) { 136 ((BasicInternalFrame)it.next()).setVisible(true); 137 } 138 if (activeFrame != null) { 139 try { 140 activeFrame.setSelected(true); 141 } catch (PropertyVetoException ex) { 142 } 143 } 144 checkSize(); 145 } 146 147 151 public void addInternalFrame(JInternalFrame frame) { 152 153 frame.addComponentListener(new ComponentAdapter() { 154 public void componentResized(ComponentEvent event) { 155 checkSize(); 156 } 157 158 }); 159 160 if (frameToMenuItem.size() == 0) { 161 separatorMenuIndex = parentFrame.menuWindow.getMenuComponentCount(); 162 parentFrame.menuWindow.addSeparator(); 163 } 164 Action action = new WindowActivateAction(frame); 165 JCheckBoxMenuItem menuItem = new JCheckBoxMenuItem(action); 166 menuItem.setSelected(false); 167 parentFrame.menuWindow.add(menuItem); 168 169 desktopPane.add(frame); 170 frameToMenuItem.put(frame, menuItem); 171 openFrames.add(frame); 172 setWindowActionsEnabled(true); 173 checkSize(); 174 } 175 176 179 public void cycleToNextWindow() { 180 cycleWindows(true); 181 } 182 183 186 public void cycleToPreviousWindow() { 187 cycleWindows(false); 188 } 189 190 193 public void tileWindows() { 194 195 int framesCount = openFrames.size(); 196 if (framesCount == 0) { 197 return; 198 } 199 200 resetSize(); 201 202 int sqrt = (int)Math.sqrt(framesCount); 203 int rows = sqrt; 204 int cols = sqrt; 205 if (rows * cols < framesCount) { 206 cols++; 207 if (rows * cols < framesCount) { 208 rows++; 209 } 210 } 211 212 Dimension size = desktopPane.getSize(); 213 214 int width = size.width/cols; 215 int height = size.height/rows; 216 int offsetX = 0; 217 int offsetY = 0; 218 219 JInternalFrame currentFrame; 220 Iterator it = openFrames.iterator(); 221 for (int i = 0; i < rows; i++) { 222 for (int j = 0; j < cols && (i * cols + j < framesCount); j++) { 223 currentFrame = (JInternalFrame)it.next(); 224 normalizeFrame(currentFrame); 225 resizeFrame(currentFrame, offsetX, offsetY, width, height); 226 offsetX += width; 227 } 228 offsetX = 0; 229 offsetY += height; 230 } 231 } 232 233 234 237 public void stackWindows() { 238 239 newInternalX = newInternalY = rollover = 0; 240 241 Rectangle currentBounds; 242 JInternalFrame currentFrame; 243 Iterator it = openFrames.iterator(); 244 while (it.hasNext()) { 245 currentFrame = (JInternalFrame)it.next(); 246 normalizeFrame(currentFrame); 247 currentBounds = getNextInternalFrameBounds(); 248 resizeFrame(currentFrame, 249 currentBounds.x, 250 currentBounds.y, 251 currentBounds.width, 252 currentBounds.height); 253 try { 254 currentFrame.setSelected(true); 255 } catch (PropertyVetoException ex) { 256 } 257 } 258 checkSize(); 259 } 260 261 public void vetoableChange(PropertyChangeEvent changeEvent) 262 throws PropertyVetoException { 263 264 String eventName = changeEvent.getPropertyName(); 265 266 if (JInternalFrame.IS_MAXIMUM_PROPERTY.equals(eventName)) { 267 if (maximizationInProgress) { 268 return; 269 } 270 271 boolean isMaximum = ((Boolean )changeEvent.getNewValue()).booleanValue(); 272 if (isMaximum) { 273 resetSize(); 274 } 275 anyFrameMaximized = isMaximum; 276 JInternalFrame source = (JInternalFrame)changeEvent.getSource(); 277 maximizeAllFrames(source, isMaximum); 278 } 279 } 280 281 public void activateFrame(JInternalFrame frame) { 282 super.activateFrame(frame); 283 Iterator it = frameToMenuItem.values().iterator(); 284 while (it.hasNext()) { 285 JCheckBoxMenuItem menuItem = (JCheckBoxMenuItem)it.next(); 286 menuItem.setSelected(false); 287 288 } 289 ((JCheckBoxMenuItem)frameToMenuItem.get(frame)).setSelected(true); 290 } 291 292 public void internalFrameDeiconified(InternalFrameEvent event) { 293 } 294 295 public void internalFrameOpened(InternalFrameEvent event) { 296 } 297 298 public void internalFrameIconified(InternalFrameEvent event) { 299 } 300 301 public void internalFrameClosing(InternalFrameEvent event) { 302 JInternalFrame frame = event.getInternalFrame(); 303 removeInternalFrame(frame); 304 } 305 306 public void internalFrameActivated(InternalFrameEvent event) { 307 } 308 309 public void internalFrameDeactivated(InternalFrameEvent event) { 310 } 311 312 public void internalFrameClosed(InternalFrameEvent event) { 313 parentFrame.desktopPane.remove(event.getInternalFrame()); 314 checkSize(); 315 } 316 317 public void endResizingFrame(JComponent f) { 318 super.endResizingFrame(f); 319 checkSize(); 320 } 321 322 public void endDraggingFrame(JComponent f) { 323 super.endDraggingFrame(f); 324 checkSize(); 325 } 326 327 330 public void checkSize() { 331 332 Dimension size = new Dimension(); 333 JInternalFrame[] frames = desktopPane.getAllFrames(); 334 for (int i = 0; i < frames.length; i++) { 335 JInternalFrame frame = frames[i]; 336 size.width = Math.max(size.width, frame.getX() + frame.getWidth()); 337 size.height = Math.max(size.height, frame.getY() + frame.getHeight()); 338 } 339 if (size.width > 0 && size.height > 0) { 340 desktopPane.setPreferredSize(size); 341 } else { 342 desktopPane.setPreferredSize(null); 343 } 344 desktopPane.revalidate(); 345 } 346 347 350 public void checkResizeInMaximizedState() { 351 if (anyFrameMaximized) { 352 resetSize(); 353 } 354 } 355 356 360 public void scrollToVisible(JInternalFrame frame) { 361 desktopPane.scrollRectToVisible(frame.getBounds()); 362 } 363 364 private void removeInternalFrame(JInternalFrame frame) { 365 366 JMenuItem menuItem = (JMenuItem)frameToMenuItem.remove(frame); 367 if (menuItem != null) { 368 parentFrame.menuWindow.remove(menuItem); 369 openFrames.remove(frame); 370 if (frameToMenuItem.size() == 0 && separatorMenuIndex > -1) { 371 parentFrame.menuWindow.remove(separatorMenuIndex); 372 separatorMenuIndex = -1; 373 setWindowActionsEnabled(false); 374 } 375 } 376 } 377 378 private void resetSize() { 379 380 desktopPane.setPreferredSize(null); 381 desktopPane.invalidate(); 382 desktopPane.getParent().validate(); 383 parentFrame.scpDesktop.invalidate(); 384 parentFrame.scpDesktop.validate(); 385 } 386 387 private void normalizeFrame(JInternalFrame frame) { 388 389 try { 390 if (frame.isIcon()) { 391 frame.setIcon(false); 392 } 393 if (frame.isMaximum()) { 394 frame.setMaximum(false); 395 } 396 } catch (PropertyVetoException ex) { 397 } 398 } 399 400 private void cycleWindows(boolean forward) { 401 402 JInternalFrame currentFrame = desktopPane.getSelectedFrame(); 403 JInternalFrame nextFrame; 404 405 ListIterator it = openFrames.listIterator(); 406 while (it.hasNext() && it.next() != currentFrame) { 407 } 408 if (forward) { 409 if (it.hasNext()) { 410 nextFrame = (JInternalFrame)it.next(); 411 } else { 412 nextFrame = (JInternalFrame)openFrames.getFirst(); 413 } 414 } else { 415 if (it.hasPrevious() && it.previous() != null && it.hasPrevious()) { 416 nextFrame = (JInternalFrame)it.previous(); 417 } else { 418 nextFrame = (JInternalFrame)openFrames.getLast(); 419 } 420 } 421 422 try { 423 if (nextFrame.isIcon()) { 424 nextFrame.setIcon(false); 425 } 426 nextFrame.setSelected(true); 427 scrollToVisible(nextFrame); 428 } catch (PropertyVetoException ex) { 429 } 430 } 431 432 private void setWindowActionsEnabled(boolean enabled) { 433 434 parentFrame.actionNextWindow.setEnabled(enabled); 435 parentFrame.actionPreviousWindow.setEnabled(enabled); 436 parentFrame.actionTileWindows.setEnabled(enabled); 437 parentFrame.actionStackWindows.setEnabled(enabled); 438 } 439 440 private void maximizeAllFrames(JInternalFrame source, boolean isMaximum) { 441 442 synchronized (this) { 443 if (maximizationInProgress) { 444 return; 445 } 446 maximizationInProgress = true; 447 } 448 449 try { 450 JInternalFrame[] frames = desktopPane.getAllFrames(); 451 for (int i = 0; i < frames.length; i++) { 452 if (frames[i] == source) { 453 continue; 454 } 455 try { 456 frames[i].setMaximum(isMaximum); 457 } catch (PropertyVetoException ex) { 458 } 459 } 460 } finally { 461 maximizationInProgress = false; 462 } 463 } 464 465 private class WindowActivateAction extends AbstractAction { 466 467 private JInternalFrame frame; 468 469 private WindowActivateAction(JInternalFrame frame) { 470 super(frame.getTitle()); 471 this.frame = frame; 472 } 473 474 public void actionPerformed(ActionEvent event) { 475 try { 476 if (frame.isIcon()) { 477 frame.setIcon(false); 478 } 479 if (frame.isSelected()) { 480 ((JCheckBoxMenuItem)event.getSource()).setSelected(true); 481 } else { 482 frame.setSelected(true); 483 } 484 scrollToVisible(frame); 485 } catch (PropertyVetoException ex) { 486 } 487 } 488 489 } 490 } 491 | Popular Tags |