View Javadoc
1 /* 2 * JScroll - the scrollable desktop pane for Java. 3 * Copyright (C) 2003 Tom Tessier 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation; either version 2 8 * of the License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 * 19 */ 20 21 package org.jscroll.widgets; 22 23 import javax.swing.*; 24 25 import java.awt.*; 26 27 28 /*** 29 * This class provides the scrollpane that contains the virtual desktop. 30 * 31 * @author <a href="mailto:tessier@gabinternet.com">Tom Tessier</a> 32 * @version 1.0 11-Aug-2001 33 */ 34 public class DesktopScrollPane extends JScrollPane { 35 private DesktopMediator desktopMediator; 36 private RootDesktopPane desktopPane; 37 private FramePositioning positioning; 38 39 /*** 40 * creates the DesktopScrollPane object 41 * 42 * @param desktopMediator a reference to the DesktopMediator object 43 */ 44 public DesktopScrollPane(DesktopMediator desktopMediator) { 45 this.desktopMediator = desktopMediator; 46 47 desktopPane = new RootDesktopPane(this); 48 setViewportView(desktopPane); 49 50 positioning = new FramePositioning(this); 51 52 // set some defaults 53 setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 54 setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); 55 56 // set scrollbars to scroll by 5 pixels each... 57 getHorizontalScrollBar().setUnitIncrement(5); 58 getVerticalScrollBar().setUnitIncrement(5); 59 } 60 61 /*** 62 * creates a JScrollInternalFrame and adds it to the virtual desktop 63 * 64 * @param dListener a reference to the DesktopListener 65 * @param title the title displayed in the title bar of the internal frame 66 * @param icon the icon displayed in the title bar of the internal frame 67 * @param frameContents the contents of the internal frame 68 * @param isClosable <code>boolean</code> indicating whether internal frame 69 * is closable 70 * @param x x coordinates of internal frame within the scrollable desktop. 71 * <code>-1</code> indicates the virtual desktop is to determine the position 72 * @param y y coordinates of internal frame within the scrollable desktop 73 * <code>-1</code> indicates the virtual desktop is to determine the position 74 * 75 * @return the JScrollInternalFrame that was created 76 */ 77 public JScrollInternalFrame add(DesktopListener dListener, String title, 78 ImageIcon icon, JPanel frameContents, boolean isClosable, int x, int y) { 79 JScrollInternalFrame f = new JScrollInternalFrame(title, icon, 80 frameContents, isClosable); 81 f.addComponentListener(dListener); 82 83 initAndAddFrame(f, x, y); 84 85 return f; 86 } 87 88 /*** 89 * adds an internal frame to the virtual desktop 90 * 91 * @param dListener a reference to the DesktopListener 92 * @param f the internal frame to add 93 * @param x x coordinates of internal frame within the scrollable desktop. 94 * <code>-1</code> indicates the virtual desktop is to determine the position 95 * @param y y coordinates of internal frame within the scrollable desktop 96 * <code>-1</code> indicates the virtual desktop is to determine the position 97 */ 98 public void add(DesktopListener dListener, JInternalFrame f, int x, int y) { 99 f.addComponentListener(dListener); 100 initAndAddFrame(f, x, y); 101 } 102 103 /*** 104 * initializes the frame for display and adds it to the desktop 105 * 106 * @param f the internal frame to add 107 * @param x x coordinates of internal frame within the scrollable desktop. 108 * <code>-1</code> indicates the virtual desktop is to determine the position 109 * @param y y coordinates of internal frame within the scrollable desktop 110 * <code>-1</code> indicates the virtual desktop is to determine the position 111 */ 112 private void initAndAddFrame(JInternalFrame f, int x, int y) { 113 // override the position of this window? 114 if ((x != -1) && (y != -1)) { 115 f.setLocation(x, y); 116 } else { 117 if (!getAutoTile()) { 118 f.setLocation(cascadeInternalFrame(f)); 119 } 120 } 121 122 desktopPane.add(f); 123 124 // select the newly added frame (note that must select it AFTER it 125 // has been added to the desktopPane) 126 try { 127 f.setSelected(true); 128 } catch (java.beans.PropertyVetoException e) { 129 // swallow property veto exceptions here..!! 130 } 131 132 // resize desktop when add a frame in case any frames off screen 133 resizeDesktop(); 134 } 135 136 /*** 137 * returns all internal frames placed upon the virtual desktop 138 * 139 * @return a JInternalFrame array containing references to the internal frames 140 */ 141 public JInternalFrame[] getAllFrames() { 142 return desktopPane.getAllFrames(); 143 } 144 145 /*** 146 * returns the internal frame currently selected upon the 147 * virtual desktop 148 * 149 * @return a reference to the active JInternalFrame 150 */ 151 public JInternalFrame getSelectedFrame() { 152 return desktopPane.getSelectedFrame(); 153 } 154 155 /*** 156 * closes the internal frame currently selected upon the 157 * virtual desktop 158 */ 159 public void closeSelectedFrame() { 160 JInternalFrame f = getSelectedFrame(); 161 162 if (f != null) { 163 f.doDefaultCloseAction(); 164 } 165 } 166 167 /*** 168 * selects the specified internal frame upon the virtual desktop 169 * 170 * @param f the internal frame to select 171 */ 172 public void setSelectedFrame(JInternalFrame f) { 173 try { 174 JInternalFrame currentFrame = desktopPane.getSelectedFrame(); 175 176 if (currentFrame != null) { 177 currentFrame.setSelected(false); 178 } 179 180 f.setSelected(true); 181 f.setIcon(false); // de-iconify it (if iconified) 182 } catch (java.beans.PropertyVetoException pve) { 183 System.out.println(pve.getMessage()); 184 } 185 } 186 187 /*** 188 * flags the specified internal frame as "contents changed." Used to 189 * notify the user when the contents of an inactive internal frame 190 * have changed. 191 * 192 * @param f the internal frame to flag as "contents changed" 193 */ 194 public void flagContentsChanged(JInternalFrame f) { 195 if (desktopPane.getSelectedFrame() != f) { 196 RootToggleButton button = (RootToggleButton) ((JScrollInternalFrame) f).getAssociatedButton(); 197 button.flagContentsChanged(true); 198 } 199 } 200 201 /*** 202 * selects the next available frame upon the virtual desktop 203 */ 204 public void selectNextFrame() { 205 JInternalFrame[] frames = getAllFrames(); 206 207 if (frames.length > 0) { 208 try { 209 frames[0].setSelected(true); 210 } catch (java.beans.PropertyVetoException pve) { 211 System.out.println("Bean veto: " + pve.getMessage()); 212 } 213 } 214 } 215 216 /*** 217 * returns the number of internal frames upon the virtual desktop 218 * 219 * @return an <code>int</code> representing the number of internal frames 220 */ 221 public int getNumberOfFrames() { 222 return desktopPane.getComponentCount(); 223 } 224 225 /*** 226 * sets the preferred size of the virtual desktop 227 * 228 * @param dim a Dimension object representing the desired preferred size 229 */ 230 public void setDesktopSize(Dimension dim) { 231 desktopPane.setPreferredSize(dim); 232 desktopPane.revalidate(); 233 } 234 235 /*** 236 * returns the preferred size of the virtual desktop 237 * 238 * @return a Dimension object representing the current preferred size 239 */ 240 public Dimension getDesktopSize() { 241 return desktopPane.getPreferredSize(); 242 } 243 244 ///// 245 // positioning methods 246 ///// 247 248 /*** 249 * propogates setAutoTile to FramePositioning 250 * 251 * @param autoTile <code>boolean</code> representing autoTile mode. 252 * If <code>true</code>, then all new frames are tiled automatically. 253 * If <code>false</code>, then all new frames are cascaded automatically. 254 */ 255 public void setAutoTile(boolean autoTile) { 256 positioning.setAutoTile(autoTile); 257 } 258 259 /*** 260 * propogates getAutoTile to FramePositioning 261 * 262 * @return <code>boolean</code> representing current autoTile mode 263 */ 264 public boolean getAutoTile() { 265 return positioning.getAutoTile(); 266 } 267 268 /*** 269 * propogates cascadeInternalFrame to FramePositioning 270 * 271 * @param f the internal frame to cascade 272 * 273 * @return a Point object representing the position of the internal frame 274 */ 275 public Point cascadeInternalFrame(JInternalFrame f) { 276 return positioning.cascadeInternalFrame(f); 277 } 278 279 /*** 280 * propogates cascadeInternalFrames to FramePositioning 281 */ 282 public void cascadeInternalFrames() { 283 positioning.cascadeInternalFrames(); 284 } 285 286 /*** 287 * propogates tileInternalFrames to FramePositioning 288 */ 289 public void tileInternalFrames() { 290 positioning.tileInternalFrames(); 291 } 292 293 /*** 294 * centers the viewport of the virtual desktop around the 295 * provided internal frame 296 * 297 * @param f the internal frame to center the viewport about 298 */ 299 public void centerView(JScrollInternalFrame f) { 300 // set the view centered around this item 301 Rectangle viewP = getViewport().getViewRect(); 302 int xCoords = (f.getX() + (f.getWidth() / 2)) - (viewP.width / 2); 303 int yCoords = (f.getY() + (f.getHeight() / 2)) - (viewP.height / 2); 304 305 Dimension desktopSize = getDesktopSize(); 306 307 if ((xCoords + viewP.width) > desktopSize.width) { 308 xCoords = desktopSize.width - viewP.width; 309 } else if (xCoords < 0) { 310 xCoords = 0; 311 } 312 313 if ((yCoords + viewP.height) > desktopSize.height) { 314 yCoords = desktopSize.height - viewP.height; 315 } else if (yCoords < 0) { 316 yCoords = 0; 317 } 318 319 getViewport().setViewPosition(new Point(xCoords, yCoords)); 320 } 321 322 /*** 323 * resizes the virtual desktop based upon the locations of its 324 * internal frames. This updates the desktop scrollbars in real-time. 325 * Executes as an "invoked later" thread for a slight perceived 326 * performance boost. 327 */ 328 public void resizeDesktop() { 329 SwingUtilities.invokeLater(new Runnable() { 330 public void run() { 331 // has to go through all the internal frames now and make sure none 332 // off screen, and if so, add those scroll bars! 333 Rectangle viewP = getViewport().getViewRect(); 334 335 int maxX = viewP.width + viewP.x; 336 int maxY = viewP.height + viewP.y; 337 int minX = viewP.x; 338 int minY = viewP.y; 339 340 // determine the min/max extents of all internal frames 341 JInternalFrame f = null; 342 JInternalFrame[] frames = getAllFrames(); 343 344 for (int i = 0; i < frames.length; i++) { 345 f = frames[i]; 346 347 if (f.getX() < minX) { // get minimum X 348 minX = f.getX(); 349 } 350 351 if ((f.getX() + f.getWidth()) > maxX) { 352 maxX = f.getX() + f.getWidth(); 353 } 354 355 if (f.getY() < minY) { // get minimum Y 356 minY = f.getY(); 357 } 358 359 if ((f.getY() + f.getHeight()) > maxY) { 360 maxY = f.getY() + f.getHeight(); 361 } 362 } 363 364 setVisible(false); // don't update the viewport while we move 365 366 // everything (otherwise desktop looks 'bouncy') 367 if ((minX != 0) || (minY != 0)) { 368 // have to scroll it to the right or up the amount that it's off screen... 369 // before scroll, move every component to the right / down by that amount 370 for (int i = 0; i < frames.length; i++) { 371 f = frames[i]; 372 f.setLocation(f.getX() - minX, f.getY() - minY); 373 } 374 375 // have to scroll (set the viewport) to the right or up the amount 376 // that it's off screen... 377 JViewport view = getViewport(); 378 view.setViewSize(new Dimension((maxX - minX), 379 (maxY - minY))); 380 view.setViewPosition(new Point((viewP.x - minX), 381 (viewP.y - minY))); 382 setViewport(view); 383 } 384 385 // resize the desktop 386 setDesktopSize(new Dimension(maxX - minX, maxY - minY)); 387 388 setVisible(true); // update the viewport again 389 } 390 }); 391 } 392 393 /*** 394 * propogates removeAssociatedComponents to DesktopMediator 395 * 396 * @param f the internal frame whose associated components are 397 * to be removed 398 */ 399 public void removeAssociatedComponents(JScrollInternalFrame f) { 400 desktopMediator.removeAssociatedComponents(f); 401 } 402 }

This page was automatically generated by Maven