001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.vmd.screen.resource;
042:
043: import java.awt.dnd.DragGestureEvent;
044: import java.awt.dnd.DropTargetDragEvent;
045: import java.awt.dnd.DropTargetDropEvent;
046: import java.awt.dnd.DropTargetEvent;
047: import org.netbeans.modules.vmd.api.model.DesignComponent;
048: import org.netbeans.modules.vmd.api.model.DesignDocument;
049: import org.netbeans.modules.vmd.api.model.presenters.InfoPresenter;
050: import org.netbeans.modules.vmd.api.model.presenters.actions.ActionsSupport;
051: import org.netbeans.modules.vmd.api.screen.resource.ScreenResourceItemPresenter;
052: import org.netbeans.modules.vmd.screen.MainPanel;
053: import org.netbeans.modules.vmd.screen.ScreenViewController;
054: import org.openide.util.Utilities;
055:
056: import javax.swing.*;
057: import javax.swing.border.Border;
058: import javax.swing.border.EmptyBorder;
059: import javax.swing.border.LineBorder;
060: import java.awt.*;
061: import java.awt.datatransfer.DataFlavor;
062: import java.awt.datatransfer.Transferable;
063: import java.awt.datatransfer.UnsupportedFlavorException;
064: import java.awt.dnd.DnDConstants;
065: import java.awt.dnd.DragGestureListener;
066: import java.awt.dnd.DragSource;
067: import java.awt.dnd.DropTarget;
068: import java.awt.dnd.DropTargetListener;
069: import java.awt.dnd.InvalidDnDOperationException;
070: import java.awt.event.MouseEvent;
071: import java.awt.event.MouseListener;
072: import java.io.IOException;
073: import java.util.ArrayList;
074: import java.util.Collection;
075: import org.netbeans.modules.vmd.api.model.common.DesignComponentDataFlavorSupport;
076:
077: /**
078: * @author breh
079: */
080: public class ResourceItemPanel extends JLabel implements MouseListener {
081:
082: private static Border SELECTED_RESOURCE_BORDER = new LineBorder(
083: MainPanel.SELECT_COLOR, 2, false);
084: private static Border HOVER_RESOURCE_BORDER = new LineBorder(
085: MainPanel.HOVER_COLOR, 2, false);
086: private static Border RESOURCE_BORDER = new EmptyBorder(2, 2, 2, 2);
087:
088: private DesignComponent component;
089: private boolean selected;
090: private boolean hovered;
091: private DragSource dragSource;
092: private DragListener listener;
093: private DropTarget dropTarget;
094:
095: public ResourceItemPanel(DesignComponent component) {
096: this .component = component;
097: setOpaque(false);
098: setBackground(Color.WHITE);
099: addMouseListener(this );
100: listener = new DragListener();
101: initDragAndDrop();
102: }
103:
104: private void initDragAndDrop() {
105: dragSource = new DragSource();
106: dropTarget = new DropTarget(this , new DropListener());
107: dragSource.createDefaultDragGestureRecognizer(this ,
108: DnDConstants.ACTION_COPY_OR_MOVE, listener);
109: }
110:
111: // called from AWT and document transaction
112: public void reload() {
113: InfoPresenter infoPresenter = component
114: .getPresenter(InfoPresenter.class);
115: ScreenResourceItemPresenter itemPresenter = component
116: .getPresenter(ScreenResourceItemPresenter.class);
117: assert infoPresenter != null : "Null InfoPresenter"; //NOI18N
118: assert itemPresenter != null : "Null ScreenResourceItemPresenter"; //NOI18N
119: InfoPresenter.NameType nameType = itemPresenter.getNameType();
120: Image image = infoPresenter
121: .getIcon(InfoPresenter.IconType.COLOR_16x16);
122: setIcon(image != null ? new ImageIcon(image) : null);
123:
124: selected = component.getDocument().getSelectedComponents()
125: .contains(component);
126: resolveBorder();
127:
128: setText(infoPresenter.getDisplayName(nameType));
129: }
130:
131: public JPopupMenu getComponentPopupMenu() {
132: return null;
133: }
134:
135: public void mouseClicked(final MouseEvent e) {
136: doSelect(e);
137: }
138:
139: private void doSelect(final MouseEvent e) {
140: final DesignDocument doc = component.getDocument();
141: final Collection<DesignComponent> newSelection = new ArrayList<DesignComponent>();
142: doc.getTransactionManager().writeAccess(new Runnable() {
143: public void run() {
144: if ((e.getModifiersEx() & MouseEvent.CTRL_DOWN_MASK) == MouseEvent.CTRL_DOWN_MASK) {
145: // invert selection
146: Collection<DesignComponent> currentSelection = doc
147: .getSelectedComponents();
148: newSelection.addAll(currentSelection);
149: if (currentSelection.contains(component)) {
150: newSelection.remove(component);
151: } else {
152: newSelection.add(component);
153: }
154: } else {
155: newSelection.add(component);
156: }
157: doc.setSelectedComponents(
158: ScreenViewController.SCREEN_ID, newSelection);
159: }
160: });
161: }
162:
163: public void mousePressed(MouseEvent e) {
164: if (e.isPopupTrigger()) {
165: doSelect(e);
166: Utilities.actionsToPopup(
167: ActionsSupport.createActionsArray(component), this )
168: .show(this , e.getX(), e.getY());
169: }
170: }
171:
172: public void mouseReleased(MouseEvent e) {
173: if (e.isPopupTrigger()) {
174: doSelect(e);
175: Utilities.actionsToPopup(
176: ActionsSupport.createActionsArray(component), this )
177: .show(this , e.getX(), e.getY());
178: }
179: }
180:
181: public void mouseEntered(MouseEvent e) {
182: hovered = true;
183: resolveBorder();
184: }
185:
186: public void mouseExited(MouseEvent e) {
187: hovered = false;
188: resolveBorder();
189: }
190:
191: private void resolveBorder() {
192: if (hovered)
193: setBorder(HOVER_RESOURCE_BORDER);
194: else
195: setBorder(selected ? SELECTED_RESOURCE_BORDER
196: : RESOURCE_BORDER);
197: }
198:
199: private class DragListener implements DragGestureListener {
200: private ScreenTransferable flavor;
201:
202: public void dragGestureRecognized(DragGestureEvent dgEvent) {
203: if (flavor == null)
204: flavor = new ScreenTransferable(component);
205: try {
206: dgEvent.startDrag(null, flavor);
207: } catch (InvalidDnDOperationException e) {
208: e.printStackTrace();
209: }
210: }
211: }
212:
213: private class DropListener implements DropTargetListener {
214:
215: public void dragEnter(DropTargetDragEvent dtde) {
216: hovered = true;
217: resolveBorder();
218: }
219:
220: public void dragOver(DropTargetDragEvent dtde) {
221: dtde.rejectDrag();
222: }
223:
224: public void dropActionChanged(DropTargetDragEvent dtde) {
225: }
226:
227: public void dragExit(DropTargetEvent dte) {
228: hovered = false;
229: resolveBorder();
230: }
231:
232: public void drop(DropTargetDropEvent dtde) {
233: }
234:
235: }
236:
237: private class ScreenTransferable implements Transferable {
238: private DesignComponent component;
239:
240: public ScreenTransferable(DesignComponent component) {
241: this .component = component;
242: }
243:
244: public DataFlavor[] getTransferDataFlavors() {
245: return new DataFlavor[] { DesignComponentDataFlavorSupport.DESIGN_COMPONENT_DATA_FLAVOR };
246: }
247:
248: public boolean isDataFlavorSupported(DataFlavor flavor) {
249: if (flavor == DesignComponentDataFlavorSupport.DESIGN_COMPONENT_DATA_FLAVOR)
250: return true;
251: return false;
252: }
253:
254: public Object getTransferData(DataFlavor flavor)
255: throws UnsupportedFlavorException, IOException {
256: if (flavor == DesignComponentDataFlavorSupport.DESIGN_COMPONENT_DATA_FLAVOR)
257: return component;
258: return null;
259: }
260: }
261:
262: }
|