1 19 20 package org.netbeans.modules.image; 21 22 import java.awt.BorderLayout ; 23 import java.awt.Color ; 24 import java.awt.Component ; 25 import java.awt.Dimension ; 26 import java.awt.Graphics ; 27 import java.awt.Image ; 28 import java.awt.event.ActionListener ; 29 import java.awt.event.ActionEvent ; 30 import java.beans.PropertyChangeEvent ; 31 import java.beans.PropertyChangeListener ; 32 import java.io.IOException ; 33 import java.io.ObjectInput ; 34 import java.io.ObjectOutput ; 35 import java.util.ArrayList ; 36 import java.util.Collection ; 37 import java.util.HashSet ; 38 import java.util.Iterator ; 39 import java.util.Set ; 40 import javax.swing.JButton ; 41 import javax.swing.JLabel ; 42 import javax.swing.JPanel ; 43 import javax.swing.JScrollPane ; 44 import javax.swing.JToolBar ; 45 import org.openide.filesystems.FileObject; 46 import org.openide.filesystems.FileUtil; 47 import org.openide.loaders.DataObject; 48 import org.openide.text.CloneableEditorSupport; 49 import org.openide.util.WeakListeners; 50 import org.openide.util.HelpCtx; 51 import org.openide.util.NbBundle; 52 import org.openide.util.Utilities; 53 import org.openide.util.actions.SystemAction; 54 import org.openide.windows.CloneableTopComponent; 55 import org.openide.windows.Mode; 56 import org.openide.windows.TopComponent; 57 import org.openide.windows.WindowManager; 58 import org.openide.windows.Workspace; 59 60 65 public class ImageViewer extends CloneableTopComponent { 66 67 68 static final long serialVersionUID =6960127954234034486L; 69 70 71 private ImageDataObject storedObject; 72 73 74 private NBImageIcon storedImage; 75 76 77 private JPanel panel; 78 79 80 private double scale = 1.0D; 81 82 83 private boolean showGrid = false; 84 85 86 private final double changeFactor = Math.sqrt(2.0D); 87 88 89 private final Color gridColor = Color.black; 90 91 92 private PropertyChangeListener nameChangeL; 93 94 95 private final Collection toolbarButtons 96 = new ArrayList (11); 97 98 99 100 public ImageViewer () { 101 super(); 102 } 103 104 107 public ImageViewer(ImageDataObject obj) { 108 initialize(obj); 109 } 110 111 113 public int getPersistenceType() { 114 return TopComponent.PERSISTENCE_ONLY_OPENED; 115 } 116 117 118 protected void reloadIcon() { 119 resizePanel(); 120 panel.repaint(); 121 } 122 123 124 private void initialize(ImageDataObject obj) { 125 TopComponent.NodeName.connect (this, obj.getNodeDelegate ()); 126 setToolTipText(FileUtil.getFileDisplayName(obj.getPrimaryFile())); 127 128 storedObject = obj; 129 130 setCloseOperation(TopComponent.CLOSE_EACH); 132 133 134 String errMsg = loadImage(storedObject); 135 136 137 JToolBar toolbar = createToolBar(); 138 Component view; 139 if (storedImage != null) { 140 view = createImageView(); 141 } else { 142 view = createMessagePanel(errMsg); 143 setToolbarButtonsEnabled(false); 144 } 145 setLayout(new BorderLayout ()); 146 add(view, BorderLayout.CENTER); 147 add(toolbar, BorderLayout.NORTH); 148 149 getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(ImageViewer.class).getString("ACS_ImageViewer")); 150 151 nameChangeL = new PropertyChangeListener () { 152 public void propertyChange(PropertyChangeEvent evt) { 153 if (DataObject.PROP_COOKIE.equals(evt.getPropertyName()) || 154 DataObject.PROP_NAME.equals(evt.getPropertyName())) { 155 updateName(); 156 } 157 } 158 }; 159 160 obj.addPropertyChangeListener(WeakListeners.propertyChange(nameChangeL, obj)); 161 } 162 163 165 private Component createImageView() { 166 panel = new JPanel () { 167 protected void paintComponent(Graphics g) { 168 super.paintComponent(g); 169 g.drawImage( 170 storedImage.getImage(), 171 0, 172 0, 173 (int)(getScale () * storedImage.getIconWidth ()), 174 (int)(getScale () * storedImage.getIconHeight ()), 175 0, 176 0, 177 storedImage.getIconWidth(), 178 storedImage.getIconHeight(), 179 this 180 ); 181 182 if(showGrid) { 183 int x = (int)(getScale () * storedImage.getIconWidth ()); 184 int y = (int)(getScale () * storedImage.getIconHeight ()); 185 186 double gridDistance = getScale(); 187 188 if(gridDistance < 2) 189 return; 191 192 g.setColor(gridColor); 193 194 double actualDistance = gridDistance; 195 for(int i = (int)actualDistance; i < x ;actualDistance += gridDistance, i = (int)actualDistance) { 196 g.drawLine(i,0,i,(y-1)); 197 } 198 199 actualDistance = gridDistance; 200 for(int j = (int)actualDistance; j < y; actualDistance += gridDistance, j = (int)actualDistance) { 201 g.drawLine(0,j,(x-1),j); 202 } 203 } 204 205 } 206 207 }; 208 storedImage.setImageObserver(panel); 209 panel.setPreferredSize(new Dimension (storedImage.getIconWidth(), storedImage.getIconHeight() )); 210 JScrollPane scroll = new JScrollPane (panel); 211 212 return scroll; 213 } 214 215 217 private Component createMessagePanel(final String msg) { 218 JPanel msgPanel = new JPanel (new java.awt.GridBagLayout ()); 219 msgPanel.add(new JLabel (msg), 220 new java.awt.GridBagConstraints ( 221 0, 0, 1, 1, 1.0d, 1.0d, java.awt.GridBagConstraints.CENTER, java.awt.GridBagConstraints.NONE, new java.awt.Insets (0, 0, 0, 0), 10, 10)); return msgPanel; 229 } 230 231 233 void updateView(final ImageDataObject imageObj) { 234 boolean wasValid = (storedImage != null); 235 String errMsg = loadImage(imageObj); 236 boolean isValid = (storedImage != null); 237 238 if (wasValid && isValid) { 239 reloadIcon(); 240 return; 241 } 242 243 Component view = (storedImage != null) ? createImageView() 244 : createMessagePanel(errMsg); 245 remove(0); 246 add(view, BorderLayout.CENTER, 0); 247 if (wasValid != isValid) { 248 setToolbarButtonsEnabled(isValid); 249 } 250 } 251 252 258 private void setToolbarButtonsEnabled(final boolean enabled) { 259 assert toolbarButtons != null; 260 261 final Iterator it = toolbarButtons.iterator(); 262 while (it.hasNext()) { 263 ((JButton ) it.next()).setEnabled(enabled); 264 } 265 } 266 267 277 private String loadImage(final ImageDataObject imageObj) { 278 String errMsg; 279 try { 280 storedImage = NBImageIcon.load(imageObj); 281 if (storedImage != null) { 282 errMsg = null; 283 } else { 284 errMsg = NbBundle.getMessage(ImageViewer.class, 285 "MSG_CouldNotLoad"); } 287 } catch (IOException ex) { 288 storedImage = null; 289 errMsg = NbBundle.getMessage(ImageViewer.class, 290 "MSG_ErrorWhileLoading"); } 292 assert (storedImage == null) != (errMsg == null); 293 return errMsg; 294 } 295 296 297 private JToolBar createToolBar() { 298 JToolBar toolBar = new JToolBar (); 300 toolBar.setFloatable (false); 301 toolBar.setName (NbBundle.getBundle(ImageViewer.class).getString("ACSN_Toolbar")); 302 toolBar.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(ImageViewer.class).getString("ACSD_Toolbar")); 303 JButton outButton = new JButton (SystemAction.get(ZoomOutAction.class)); 304 outButton.setToolTipText (NbBundle.getBundle(ImageViewer.class).getString("LBL_ZoomOut")); 305 outButton.setMnemonic(NbBundle.getBundle(ImageViewer.class).getString("ACS_Out_BTN_Mnem").charAt(0)); 306 outButton.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(ImageViewer.class).getString("ACSD_Out_BTN")); 307 outButton.setText(""); 308 toolBar.add(outButton); 309 toolbarButtons.add(outButton); 310 toolBar.addSeparator(new Dimension (2,2)); 311 JButton inButton = new JButton (SystemAction.get(ZoomInAction.class)); 312 inButton.setToolTipText (NbBundle.getBundle(ImageViewer.class).getString("LBL_ZoomIn")); 313 inButton.setMnemonic(NbBundle.getBundle(ImageViewer.class).getString("ACS_In_BTN_Mnem").charAt(0)); 314 inButton.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(ImageViewer.class).getString("ACSD_In_BTN")); 315 inButton.setText(""); 316 toolBar.add(inButton); 317 toolbarButtons.add(inButton); 318 toolBar.addSeparator(new Dimension (11,2)); 319 320 JButton button; 321 322 toolBar.add(button = getZoomButton(1,1)); 323 toolbarButtons.add(button); 324 toolBar.addSeparator(new Dimension (11,2)); 325 toolBar.add(button = getZoomButton(1,3)); 326 toolbarButtons.add(button); 327 toolBar.addSeparator(new Dimension (2,2)); 328 toolBar.add(button = getZoomButton(1,5)); 329 toolbarButtons.add(button); 330 toolBar.addSeparator(new Dimension (2,2)); 331 toolBar.add(button = getZoomButton(1,7)); 332 toolbarButtons.add(button); 333 toolBar.addSeparator(new Dimension (11,2)); 334 toolBar.add(button = getZoomButton(3,1)); 335 toolbarButtons.add(button); 336 toolBar.addSeparator(new Dimension (2,2)); 337 toolBar.add(button = getZoomButton(5,1)); 338 toolbarButtons.add(button); 339 toolBar.addSeparator(new Dimension (2,2)); 340 toolBar.add(button = getZoomButton(7,1)); 341 toolbarButtons.add(button); 342 toolBar.addSeparator(new Dimension (11,2)); 343 toolBar.add (button = getZoomButton ()); 346 toolbarButtons.add(button); 347 toolBar.addSeparator(new Dimension (11,2)); 348 toolBar.add(button = getGridButton()); 349 toolbarButtons.add(button); 350 351 return toolBar; 352 } 353 354 355 private void updateName () { 356 String name = storedObject.getNodeDelegate().getDisplayName(); 358 setName(name); 359 FileObject fo = storedObject.getPrimaryFile(); 361 setToolTipText(FileUtil.getFileDisplayName(fo)); 362 } 363 364 367 public void open(Workspace workspace){ 368 if (discard()) return; 369 370 Workspace realWorkspace = (workspace == null) 371 ? WindowManager.getDefault().getCurrentWorkspace() 372 : workspace; 373 dockIfNeeded(realWorkspace); 374 boolean modeVisible = false; 375 TopComponent[] tcArray = editorMode(realWorkspace).getTopComponents(); 376 for (int i = 0; i < tcArray.length; i++) { 377 if (tcArray[i].isOpened(realWorkspace)) { 378 modeVisible = true; 379 break; 380 } 381 } 382 if (!modeVisible) { 383 openOtherEditors(realWorkspace); 384 } 385 super.open(workspace); 386 openOnOtherWorkspaces(realWorkspace); 387 } 388 389 391 protected String preferredID() { 392 return getClass().getName(); 393 } 394 395 private void superOpen(Workspace workspace) { 396 super.open(workspace); 397 } 398 399 400 403 private void openOnOtherWorkspaces(Workspace workspace) { 404 Workspace[] workspaces = WindowManager.getDefault().getWorkspaces(); 405 Mode curEditorMode = null; 406 Mode tcMode = null; 407 for (int i = 0; i < workspaces.length; i++) { 408 if (workspaces[i].equals(workspace)) { 410 continue; 411 } 412 curEditorMode = workspaces[i].findMode(CloneableEditorSupport.EDITOR_MODE); 413 tcMode = workspaces[i].findMode(this); 414 if ( 415 !isOpened(workspaces[i]) && 416 curEditorMode != null && 417 ( 418 tcMode == null || 419 tcMode.equals(curEditorMode) 420 ) 421 ) { 422 TopComponent[] tcArray = curEditorMode.getTopComponents(); 425 for (int j = 0; j < tcArray.length; j++) { 426 if (tcArray[j].isOpened(workspaces[i])) { 427 pureOpen(this, workspaces[i]); 429 break; 430 } 431 } 432 } 433 } 434 } 435 436 440 private void openOtherEditors(Workspace workspace) { 441 Set topComps = new HashSet (15); 443 Workspace[] wsArray = WindowManager.getDefault().getWorkspaces(); 444 Mode curEditorMode = null; 445 TopComponent[] tcArray = null; 446 for (int i = 0; i < wsArray.length; i++) { 447 curEditorMode = wsArray[i].findMode(CloneableEditorSupport.EDITOR_MODE); 448 if (curEditorMode != null) { 449 tcArray = curEditorMode.getTopComponents(); 450 for (int j = 0; j < tcArray.length; j++) { 451 if (tcArray[j].isOpened(wsArray[i])) { 452 topComps.add(tcArray[j]); 453 } 454 } 455 } 456 } 457 for (Iterator iter = topComps.iterator(); iter.hasNext(); ) { 459 pureOpen((TopComponent)iter.next(), workspace); 460 } 461 } 462 463 467 private void pureOpen(TopComponent tc,Workspace workspace) { 468 if (tc instanceof ImageViewer) { 469 ((ImageViewer)tc).dockIfNeeded(workspace); 470 ((ImageViewer)tc).superOpen(workspace); 471 } else { 472 tc.open(workspace); 473 } 474 } 475 476 478 private void dockIfNeeded(Workspace workspace) { 479 Mode ourMode = workspace.findMode(this); 481 if (ourMode == null) { 482 editorMode(workspace).dockInto(this); 483 } 484 } 485 486 private Mode editorMode(Workspace workspace) { 487 Mode ourMode = workspace.findMode(this); 488 if (ourMode == null) { 489 ourMode = workspace.createMode( 490 CloneableEditorSupport.EDITOR_MODE, getName(), 491 CloneableEditorSupport.class.getResource( 492 "/org/openide/resources/editorMode.gif" ) 494 ); 495 } 496 return ourMode; 497 } 498 499 500 public HelpCtx getHelpCtx () { 501 return HelpCtx.DEFAULT_HELP; 502 } 503 504 507 private boolean discard () { 508 return storedObject == null; 509 } 510 511 515 public void writeExternal (ObjectOutput out) 516 throws IOException { 517 super.writeExternal(out); 518 out.writeObject(storedObject); 519 } 520 521 526 public void readExternal (ObjectInput in) 527 throws IOException , ClassNotFoundException { 528 super.readExternal(in); 529 storedObject = (ImageDataObject)in.readObject(); 530 ((ImageOpenSupport)storedObject.getCookie(ImageOpenSupport.class)).prepareViewer(); 532 initialize(storedObject); 533 } 534 535 536 protected CloneableTopComponent createClonedObject () { 537 return new ImageViewer(storedObject); 538 } 539 540 541 public SystemAction[] getSystemActions() { 542 SystemAction[] oldValue = super.getSystemActions(); 543 return SystemAction.linkActions(new SystemAction[] { 544 SystemAction.get(ZoomInAction.class), 545 SystemAction.get(ZoomOutAction.class), 546 SystemAction.get(CustomZoomAction.class), 547 null}, 548 oldValue); 549 } 550 551 552 public Image getIcon () { 553 return Utilities.loadImage("org/netbeans/modules/image/imageObject.png"); } 555 556 557 public void zoomIn() { 558 scaleIn(); 559 resizePanel(); 560 panel.repaint(0, 0, panel.getWidth(), panel.getHeight()); 561 } 562 563 564 public void zoomOut() { 565 double oldScale = scale; 566 567 scaleOut(); 568 569 if(!isNewSizeOK()) { 571 scale = oldScale; 572 573 return; 574 } 575 576 resizePanel(); 577 panel.repaint(0, 0, panel.getWidth(), panel.getHeight()); 578 } 579 580 581 private void resizePanel() { 582 panel.setPreferredSize(new Dimension ( 583 (int)(getScale () * storedImage.getIconWidth ()), 584 (int)(getScale () * storedImage.getIconHeight())) 585 ); 586 panel.revalidate(); 587 } 588 589 592 private boolean isNewSizeOK() { 593 if (((getScale () * storedImage.getIconWidth ()) > 1) && 594 ((getScale () * storedImage.getIconWidth ()) > 1) 595 ) return true; 596 return false; 597 } 598 599 603 public void customZoom(int fx, int fy) { 604 double oldScale = scale; 605 606 scale = (double)fx/(double)fy; 607 if(!isNewSizeOK()) { 608 scale = oldScale; 609 610 return; 611 } 612 613 resizePanel(); 614 panel.repaint(0, 0, panel.getWidth(), panel.getHeight()); 615 } 616 617 618 private double getScale () { 619 return scale; 620 } 621 622 623 private void scaleOut() { 624 scale = scale / changeFactor; 625 } 626 627 628 private void scaleIn() { 629 double oldComputedScale = getScale (); 630 631 scale = changeFactor * scale; 632 633 double newComputedScale = getScale(); 634 635 if (newComputedScale == oldComputedScale) 636 scale = newComputedScale + 1.0D; 638 } 639 640 641 private JButton getZoomButton(final int xf, final int yf) { 642 JButton button = new JButton (""+xf+":"+yf); if (xf < yf) 645 button.setToolTipText (NbBundle.getBundle(ImageViewer.class).getString("LBL_ZoomOut") + " " + xf + " : " + yf); 646 else 647 button.setToolTipText (NbBundle.getBundle(ImageViewer.class).getString("LBL_ZoomIn") + " " + xf + " : " + yf); 648 button.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(ImageViewer.class).getString("ACS_Zoom_BTN")); 649 button.addActionListener(new ActionListener () { 650 public void actionPerformed(ActionEvent evt) { 651 customZoom(xf, yf); 652 } 653 }); 654 655 return button; 656 } 657 658 private JButton getZoomButton() { 659 JButton button = new JButton (NbBundle.getBundle(CustomZoomAction.class).getString("LBL_XtoY")); button.setToolTipText (NbBundle.getBundle(ImageViewer.class).getString("LBL_CustomZoom")); 662 button.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(ImageViewer.class).getString("ACS_Zoom_BTN")); 663 button.addActionListener(new ActionListener () { 664 public void actionPerformed(ActionEvent evt) { 665 CustomZoomAction sa = (CustomZoomAction) SystemAction.get(CustomZoomAction.class); 666 sa.performAction (); 667 } 668 }); 669 670 return button; 671 } 672 673 674 private JButton getGridButton() { 675 final JButton button = new JButton (" # "); button.setToolTipText (NbBundle.getBundle(ImageViewer.class).getString("LBL_ShowHideGrid")); 678 button.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(ImageViewer.class).getString("ACS_Grid_BTN")); 679 button.setMnemonic(NbBundle.getBundle(ImageViewer.class).getString("ACS_Grid_BTN_Mnem").charAt(0)); 680 button.addActionListener(new ActionListener () { 681 public void actionPerformed(ActionEvent evt) { 682 showGrid = !showGrid; 683 panel.repaint(0, 0, panel.getWidth(), panel.getHeight()); 684 } 685 }); 686 687 return button; 688 } 689 690 } 691 | Popular Tags |