/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package photoSpreadObjects.photoSpreadComponents; import java.awt.Graphics; import java.awt.Image; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.MouseEvent; import java.rmi.NotBoundException; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.event.MouseInputAdapter; import photoSpread.PhotoSpread; import photoSpreadObjects.PhotoSpreadObject; import photoSpreadTable.DnDSupport; import photoSpreadTable.PhotoSpreadCell; import photoSpreadUtilities.ComputableDimension; import photoSpreadUtilities.Const; import photoSpreadUtilities.Misc; import photoSpreadUtilities.PhotoSpreadContextMenu; /** * * @author skandel */ public class DraggableLabel extends JLabel implements PhotoSpreadAddable { /** * */ private static final long serialVersionUID = 1L; private PhotoSpreadObject _parentObject; private PhotoSpreadCell _cell; private ComputableDimension _imageSize = new ComputableDimension(0, 0); private ComputableDimension _unscaledSize = null; /**************************************************** * Constructor(s) *****************************************************/ // Pass the object that this label represents (e.g. an image): public DraggableLabel(PhotoSpreadObject _parentObject) { this._parentObject = _parentObject; this._cell = null; initialize(); } public DraggableLabel(PhotoSpreadObject _parentObject, int height, int width) { this(_parentObject); _imageSize = (new ComputableDimension(width, height)); } public DraggableLabel(Icon arg0, PhotoSpreadObject _parentObject) { super(arg0); this._parentObject = _parentObject; initialize(); } public DraggableLabel(Icon image, int horizontalAlignment, PhotoSpreadObject _parentObject) { super(image, horizontalAlignment); this._parentObject = _parentObject; initialize(); _imageSize = (new ComputableDimension(image.getIconWidth(), image.getIconHeight())); } public DraggableLabel(String text, PhotoSpreadObject _parentObject) { super(text); this._parentObject = _parentObject; initialize(); _imageSize = (new ComputableDimension(this.getSize())); } public DraggableLabel(String text, int horizontalAlignment, PhotoSpreadObject _parentObject) { super(text, horizontalAlignment); this._parentObject = _parentObject; initialize(); _imageSize = (new ComputableDimension(this.getSize())); } public DraggableLabel(String text, Icon image, int horizontalAlignment, PhotoSpreadObject _parentObject) { super(text, image, horizontalAlignment); this._parentObject = _parentObject; initialize(); _imageSize = (new ComputableDimension(this.getSize())); } /**************************************************** * Methods *****************************************************/ /* (non-Javadoc) * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)\ * * We need to override pointComponent(), so that images * are properly resized in the Workspace when the size * slider is operated. Without this override, the images * get clipped, rather than sized. */ @Override protected void paintComponent (Graphics g) { super.paintComponent (g); ImageIcon theIcon = (ImageIcon)getIcon(); // For 'text' draggable labels, the Icon part of this DraggableLabel is null: if (theIcon != null) { Image theImage = theIcon.getImage(); if (theImage != null) g.drawImage (theImage, 0, 0, getWidth (), getHeight (), null); } } public void setCell(PhotoSpreadCell cell){ this._cell = cell; } public PhotoSpreadCell getCell(){ return _cell; } public JComponent getComponent(){ return this; } public PhotoSpreadObject getParentObject(){ return _parentObject; } public void setUnscaledSize(int x, int y) { _unscaledSize = new ComputableDimension(x, y); } public void setUnscaledSize(ComputableDimension dim) { _unscaledSize = dim; } /** * Returns the dimensions of the original image, if this * label wraps an image. These dimensions are the size * of the original image file. * * @return _unscaledSize if it was set, else null: */ public ComputableDimension getUnscaledSize() { return _unscaledSize; } /** * highlights the label */ public void highlight(){ this.setBorder(Const.labelHighlightBorder); } /** * removes highlight from label */ public void unhighlight(){ this.setBorder(null); } public boolean isHighlighted() { if (this.getBorder() != null) return true; else return false; } public Insets insets () { return Const.draggableLabelInsets; } /** * Returns the original size of the represented object. * @return the _originalSize */ public ComputableDimension getNaturalSize() { int maxWidth = 0; int maxHeight= 0; maxWidth = PhotoSpread.photoSpreadPrefs.getInt(PhotoSpread.workspaceMaxObjWidthKey); maxHeight = PhotoSpread.photoSpreadPrefs.getInt(PhotoSpread.workspaceMaxObjHeightKey); if (_imageSize.compareTo( new ComputableDimension(maxWidth, maxHeight)) == Const.BIGGER) return new ComputableDimension(maxWidth, maxHeight); else return _imageSize; } public int compareTo(PhotoSpreadAddable thatAddable) { return this._imageSize.compareTo(thatAddable.getNaturalSize()); } private void initialize(){ makeDraggable(); addMenu(); /* setBorder(BorderFactory.createEmptyBorder( 3, // top 100, // left 3, // bottom 10)); // right */ } private void addMenu(){ PhotoSpreadContextMenu menu = new PhotoSpreadContextMenu(); // Contex menu item Edit Metadata: menu.addMenuItem("Edit Metadata", new java.awt.event.ActionListener() { public void actionPerformed(ActionEvent e) { editMetaData(); } // end Edit Metadata action performed } // end Edit Metadata action listener ); // end Edit Metadata add menu /* // Contex menu item Select All: menu.addMenuItem("Select All", new java.awt.event.ActionListener() { public void actionPerformed(ActionEvent e) { selectAll(); } // end SelectAll action performed } // end SelectAll action listener ); // end SelectAll add menu */ this.addMouseListener(menu.getPopupListener()); } /** * Return a new metadata editor that's open * and visible. * @return */ private MetadataEditor editMetaData() { MetadataEditor editor = new MetadataEditor(); editor.setSize(PhotoSpread.photoSpreadPrefs.getDimension(PhotoSpread.editorSizeKey)); try { editor.setEditedObject(this._parentObject); } catch (NumberFormatException e) { Misc.showErrorMsgAndStackTrace(e, "Fatal error."); //System.out.println(e.getMessage()); //e.printStackTrace(); System.exit(-1); } catch (NotBoundException e) { Misc.showErrorMsgAndStackTrace(e, "Fatal error."); //System.out.println(e.getMessage()); //e.printStackTrace(); System.exit(-1); } editor.setVisible(true); return editor; } /* private void selectAll() { // Get all objects in the enclosing cell // and call highlight on each of them. This // takes care of making the View look highlit: Iterator<PhotoSpreadObject> it = _cell.getObjectsIterator(); while (it.hasNext()) { it.next()).highlight(); } // Now make the cell Model know that all its contents // are highlit: _cell.selectAllObjects(); } */ /** * @author paepcke * This class listens for mouse events on an individual item * (e.g. image). It handles single clicks (selection), and * double-clicks (start Metadata Editor). * * In addition, it solves the following problem: the * user selects an image in the workspace, and drags it to the sheet window. * They now go back to the Workspace window, click-down on * a second image, and start dragging it right away, before * releasing the mouse. Without the action of this class, * the originally selected image is still selected, and gets * dragged a second time. * * To avoid this confusing inconvenience, Workspace listens for * Workspace-window focus-gained events (see Workspace.java}. * If the Workspace sees such an event, it sets the * maybeFocusPlusDragEvent flag to true. * * Each DraggableLabel, when detecting a drag event (mouseDragged()), * checks whether it resides in the current Workspace, and whether * that Workspace just gained focus, without the mouse having been * release before the drag. If so, we de-select everything * in the Workspace window, and select only the item being dragged, * i.e. this item. */ private class PhotoSpreadMouseMotionListener extends MouseInputAdapter { @Override public void mouseReleased(MouseEvent e) { if(e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2){ ((DraggableLabel) e.getSource()).editMetaData(); } if(e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 1){ int clickType = ObjectsPanel.NORMAL_LEFT_CLICK; int clickModifier = e.getModifiersEx(); if ((clickModifier & ObjectsPanel.SHIFT_LEFT_CLICK) == ObjectsPanel.SHIFT_LEFT_CLICK) { clickType = ObjectsPanel.SHIFT_LEFT_CLICK; } if ((clickModifier & ObjectsPanel.CTRL_LEFT_CLICK) == ObjectsPanel.CTRL_LEFT_CLICK) { clickType = ObjectsPanel.CTRL_LEFT_CLICK; } // If this DraggableLabel is embedded in a table // cell, then act on the mouse button release. // Else ignore the release: try { ((ObjectsPanel) DraggableLabel.this.getParent()). clickLabel((DraggableLabel) e.getSource(), clickType); } catch (ClassCastException exception) { // Just ignore } } } @Override public void mouseDragged(MouseEvent e) { Workspace ws = PhotoSpread.getCurrentWorkspaceWindow(); if (!ws.isObjectSelected(DraggableLabel.this)) { ws.deSelectAll(); ws.selectObject(DraggableLabel.this); return; } } } private void makeDraggable() { this.setTransferHandler(new DnDSupport.TransferHandlerLabel()); PhotoSpreadMouseMotionListener mouseListener = new PhotoSpreadMouseMotionListener(); this.addMouseListener(mouseListener); this.addMouseMotionListener(mouseListener); } }