History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/awt/dnd/DragSourceContext.java (1 of 18352 files). Show all

Unified · Split

java/pkg/java/awt/dnd/DragSourceContext.java+634−0
@@ -0,0 +1,634 @@
1+/*
2+ * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package java.awt.dnd;
27+
28+import java.awt.Component;
29+import java.awt.Cursor;
30+import java.awt.Image;
31+import java.awt.Point;
32+
33+import java.awt.datatransfer.DataFlavor;
34+import java.awt.datatransfer.Transferable;
35+import java.awt.datatransfer.UnsupportedFlavorException;
36+
37+import java.awt.dnd.peer.DragSourceContextPeer;
38+
39+import java.io.IOException;
40+import java.io.ObjectOutputStream;
41+import java.io.ObjectInputStream;
42+import java.io.Serializable;
43+
44+import java.util.TooManyListenersException;
45+
46+/**
47+ * The <code>DragSourceContext</code> class is responsible for managing the
48+ * initiator side of the Drag and Drop protocol. In particular, it is responsible
49+ * for managing drag event notifications to the
50+ * {@linkplain DragSourceListener DragSourceListeners}
51+ * and {@linkplain DragSourceMotionListener DragSourceMotionListeners}, and providing the
52+ * {@link Transferable} representing the source data for the drag operation.
53+ * <p>
54+ * Note that the <code>DragSourceContext</code> itself
55+ * implements the <code>DragSourceListener</code> and
56+ * <code>DragSourceMotionListener</code> interfaces.
57+ * This is to allow the platform peer
58+ * (the {@link DragSourceContextPeer} instance)
59+ * created by the {@link DragSource} to notify
60+ * the <code>DragSourceContext</code> of
61+ * state changes in the ongoing operation. This allows the
62+ * <code>DragSourceContext</code> object to interpose
63+ * itself between the platform and the
64+ * listeners provided by the initiator of the drag operation.
65+ * <p>
66+ * <a name="defaultCursor" />
67+ * By default, {@code DragSourceContext} sets the cursor as appropriate
68+ * for the current state of the drag and drop operation. For example, if
69+ * the user has chosen {@linkplain DnDConstants#ACTION_MOVE the move action},
70+ * and the pointer is over a target that accepts
71+ * the move action, the default move cursor is shown. When
72+ * the pointer is over an area that does not accept the transfer,
73+ * the default "no drop" cursor is shown.
74+ * <p>
75+ * This default handling mechanism is disabled when a custom cursor is set
76+ * by the {@link #setCursor} method. When the default handling is disabled,
77+ * it becomes the responsibility
78+ * of the developer to keep the cursor up to date, by listening
79+ * to the {@code DragSource} events and calling the {@code setCursor()} method.
80+ * Alternatively, you can provide custom cursor behavior by providing
81+ * custom implementations of the {@code DragSource}
82+ * and the {@code DragSourceContext} classes.
83+ *
84+ * @see DragSourceListener
85+ * @see DragSourceMotionListener
86+ * @see DnDConstants
87+ * @since 1.2
88+ */
89+
90+public class DragSourceContext
91+ implements DragSourceListener, DragSourceMotionListener, Serializable {
92+
93+ private static final long serialVersionUID = -115407898692194719L;
94+
95+ // used by updateCurrentCursor
96+
97+ /**
98+ * An <code>int</code> used by updateCurrentCursor()
99+ * indicating that the <code>Cursor</code> should change
100+ * to the default (no drop) <code>Cursor</code>.
101+ */
102+ protected static final int DEFAULT = 0;
103+
104+ /**
105+ * An <code>int</code> used by updateCurrentCursor()
106+ * indicating that the <code>Cursor</code>
107+ * has entered a <code>DropTarget</code>.
108+ */
109+ protected static final int ENTER = 1;
110+
111+ /**
112+ * An <code>int</code> used by updateCurrentCursor()
113+ * indicating that the <code>Cursor</code> is
114+ * over a <code>DropTarget</code>.
115+ */
116+ protected static final int OVER = 2;
117+
118+ /**
119+ * An <code>int</code> used by updateCurrentCursor()
120+ * indicating that the user operation has changed.
121+ */
122+
123+ protected static final int CHANGED = 3;
124+
125+ /**
126+ * Called from <code>DragSource</code>, this constructor creates a new
127+ * <code>DragSourceContext</code> given the
128+ * <code>DragSourceContextPeer</code> for this Drag, the
129+ * <code>DragGestureEvent</code> that triggered the Drag, the initial
130+ * <code>Cursor</code> to use for the Drag, an (optional)
131+ * <code>Image</code> to display while the Drag is taking place, the offset
132+ * of the <code>Image</code> origin from the hotspot at the instant of the
133+ * triggering event, the <code>Transferable</code> subject data, and the
134+ * <code>DragSourceListener</code> to use during the Drag and Drop
135+ * operation.
136+ * <br>
137+ * If <code>DragSourceContextPeer</code> is <code>null</code>
138+ * <code>NullPointerException</code> is thrown.
139+ * <br>
140+ * If <code>DragGestureEvent</code> is <code>null</code>
141+ * <code>NullPointerException</code> is thrown.
142+ * <br>
143+ * If <code>Cursor</code> is <code>null</code> no exception is thrown and
144+ * the default drag cursor behavior is activated for this drag operation.
145+ * <br>
146+ * If <code>Image</code> is <code>null</code> no exception is thrown.
147+ * <br>
148+ * If <code>Image</code> is not <code>null</code> and the offset is
149+ * <code>null</code> <code>NullPointerException</code> is thrown.
150+ * <br>
151+ * If <code>Transferable</code> is <code>null</code>
152+ * <code>NullPointerException</code> is thrown.
153+ * <br>
154+ * If <code>DragSourceListener</code> is <code>null</code> no exception
155+ * is thrown.
156+ *
157+ * @param dscp the <code>DragSourceContextPeer</code> for this drag
158+ * @param trigger the triggering event
159+ * @param dragCursor the initial {@code Cursor} for this drag operation
160+ * or {@code null} for the default cursor handling;
161+ * see <a href="DragSourceContext.html#defaultCursor">class level documentation</a>
162+ * for more details on the cursor handling mechanism during drag and drop
163+ * @param dragImage the <code>Image</code> to drag (or <code>null</code>)
164+ * @param offset the offset of the image origin from the hotspot at the
165+ * instant of the triggering event
166+ * @param t the <code>Transferable</code>
167+ * @param dsl the <code>DragSourceListener</code>
168+ *
169+ * @throws IllegalArgumentException if the <code>Component</code> associated
170+ * with the trigger event is <code>null</code>.
171+ * @throws IllegalArgumentException if the <code>DragSource</code> for the
172+ * trigger event is <code>null</code>.
173+ * @throws IllegalArgumentException if the drag action for the
174+ * trigger event is <code>DnDConstants.ACTION_NONE</code>.
175+ * @throws IllegalArgumentException if the source actions for the
176+ * <code>DragGestureRecognizer</code> associated with the trigger
177+ * event are equal to <code>DnDConstants.ACTION_NONE</code>.
178+ * @throws NullPointerException if dscp, trigger, or t are null, or
179+ * if dragImage is non-null and offset is null
180+ */
181+ public DragSourceContext(DragSourceContextPeer dscp,
182+ DragGestureEvent trigger, Cursor dragCursor,
183+ Image dragImage, Point offset, Transferable t,
184+ DragSourceListener dsl) {
185+ if (dscp == null) {
186+ throw new NullPointerException("DragSourceContextPeer");
187+ }
188+
189+ if (trigger == null) {
190+ throw new NullPointerException("Trigger");
191+ }
192+
193+ if (trigger.getDragSource() == null) {
194+ throw new IllegalArgumentException("DragSource");
195+ }
196+
197+ if (trigger.getComponent() == null) {
198+ throw new IllegalArgumentException("Component");
199+ }
200+
201+ if (trigger.getSourceAsDragGestureRecognizer().getSourceActions() ==
202+ DnDConstants.ACTION_NONE) {
203+ throw new IllegalArgumentException("source actions");
204+ }
205+
206+ if (trigger.getDragAction() == DnDConstants.ACTION_NONE) {
207+ throw new IllegalArgumentException("no drag action");
208+ }
209+
210+ if (t == null) {
211+ throw new NullPointerException("Transferable");
212+ }
213+
214+ if (dragImage != null && offset == null) {
215+ throw new NullPointerException("offset");
216+ }
217+
218+ peer = dscp;
219+ this.trigger = trigger;
220+ cursor = dragCursor;
221+ transferable = t;
222+ listener = dsl;
223+ sourceActions =
224+ trigger.getSourceAsDragGestureRecognizer().getSourceActions();
225+
226+ useCustomCursor = (dragCursor != null);
227+
228+ updateCurrentCursor(trigger.getDragAction(), getSourceActions(), DEFAULT);
229+ }
230+
231+ /**
232+ * Returns the <code>DragSource</code>
233+ * that instantiated this <code>DragSourceContext</code>.
234+ *
235+ * @return the <code>DragSource</code> that
236+ * instantiated this <code>DragSourceContext</code>
237+ */
238+
239+ public DragSource getDragSource() { return trigger.getDragSource(); }
240+
241+ /**
242+ * Returns the <code>Component</code> associated with this
243+ * <code>DragSourceContext</code>.
244+ *
245+ * @return the <code>Component</code> that started the drag
246+ */
247+
248+ public Component getComponent() { return trigger.getComponent(); }
249+
250+ /**
251+ * Returns the <code>DragGestureEvent</code>
252+ * that initially triggered the drag.
253+ *
254+ * @return the Event that triggered the drag
255+ */
256+
257+ public DragGestureEvent getTrigger() { return trigger; }
258+
259+ /**
260+ * Returns a bitwise mask of <code>DnDConstants</code> that
261+ * represent the set of drop actions supported by the drag source for the
262+ * drag operation associated with this <code>DragSourceContext</code>.
263+ *
264+ * @return the drop actions supported by the drag source
265+ */
266+ public int getSourceActions() {
267+ return sourceActions;
268+ }
269+
270+ /**
271+ * Sets the cursor for this drag operation to the specified
272+ * <code>Cursor</code>. If the specified <code>Cursor</code>
273+ * is <code>null</code>, the default drag cursor behavior is
274+ * activated for this drag operation, otherwise it is deactivated.
275+ *
276+ * @param c the initial {@code Cursor} for this drag operation,
277+ * or {@code null} for the default cursor handling;
278+ * see {@linkplain Cursor class
279+ * level documentation} for more details
280+ * on the cursor handling during drag and drop
281+ *
282+ */
283+
284+ public synchronized void setCursor(Cursor c) {
285+ useCustomCursor = (c != null);
286+ setCursorImpl(c);
287+ }
288+
289+ /**
290+ * Returns the current drag <code>Cursor</code>.
291+ * <P>
292+ * @return the current drag <code>Cursor</code>
293+ */
294+
295+ public Cursor getCursor() { return cursor; }
296+
297+ /**
298+ * Add a <code>DragSourceListener</code> to this
299+ * <code>DragSourceContext</code> if one has not already been added.
300+ * If a <code>DragSourceListener</code> already exists,
301+ * this method throws a <code>TooManyListenersException</code>.
302+ * <P>
303+ * @param dsl the <code>DragSourceListener</code> to add.
304+ * Note that while <code>null</code> is not prohibited,
305+ * it is not acceptable as a parameter.
306+ * <P>
307+ * @throws TooManyListenersException if
308+ * a <code>DragSourceListener</code> has already been added
309+ */
310+
311+ public synchronized void addDragSourceListener(DragSourceListener dsl) throws TooManyListenersException {
312+ if (dsl == null) return;
313+
314+ if (equals(dsl)) throw new IllegalArgumentException("DragSourceContext may not be its own listener");
315+
316+ if (listener != null)
317+ throw new TooManyListenersException();
318+ else
319+ listener = dsl;
320+ }
321+
322+ /**
323+ * Removes the specified <code>DragSourceListener</code>
324+ * from this <code>DragSourceContext</code>.
325+ *
326+ * @param dsl the <code>DragSourceListener</code> to remove;
327+ * note that while <code>null</code> is not prohibited,
328+ * it is not acceptable as a parameter
329+ */
330+
331+ public synchronized void removeDragSourceListener(DragSourceListener dsl) {
332+ if (listener != null && listener.equals(dsl)) {
333+ listener = null;
334+ } else
335+ throw new IllegalArgumentException();
336+ }
337+
338+ /**
339+ * Notifies the peer that the <code>Transferable</code>'s
340+ * <code>DataFlavor</code>s have changed.
341+ */
342+
343+ public void transferablesFlavorsChanged() {
344+ if (peer != null) peer.transferablesFlavorsChanged();
345+ }
346+
347+ /**
348+ * Calls <code>dragEnter</code> on the
349+ * <code>DragSourceListener</code>s registered with this
350+ * <code>DragSourceContext</code> and with the associated
351+ * <code>DragSource</code>, and passes them the specified
352+ * <code>DragSourceDragEvent</code>.
353+ *
354+ * @param dsde the <code>DragSourceDragEvent</code>
355+ */
356+ public void dragEnter(DragSourceDragEvent dsde) {
357+ DragSourceListener dsl = listener;
358+ if (dsl != null) {
359+ dsl.dragEnter(dsde);
360+ }
361+ getDragSource().processDragEnter(dsde);
362+
363+ updateCurrentCursor(getSourceActions(), dsde.getTargetActions(), ENTER);
364+ }
365+
366+ /**
367+ * Calls <code>dragOver</code> on the
368+ * <code>DragSourceListener</code>s registered with this
369+ * <code>DragSourceContext</code> and with the associated
370+ * <code>DragSource</code>, and passes them the specified
371+ * <code>DragSourceDragEvent</code>.
372+ *
373+ * @param dsde the <code>DragSourceDragEvent</code>
374+ */
375+ public void dragOver(DragSourceDragEvent dsde) {
376+ DragSourceListener dsl = listener;
377+ if (dsl != null) {
378+ dsl.dragOver(dsde);
379+ }
380+ getDragSource().processDragOver(dsde);
381+
382+ updateCurrentCursor(getSourceActions(), dsde.getTargetActions(), OVER);
383+ }
384+
385+ /**
386+ * Calls <code>dragExit</code> on the
387+ * <code>DragSourceListener</code>s registered with this
388+ * <code>DragSourceContext</code> and with the associated
389+ * <code>DragSource</code>, and passes them the specified
390+ * <code>DragSourceEvent</code>.
391+ *
392+ * @param dse the <code>DragSourceEvent</code>
393+ */
394+ public void dragExit(DragSourceEvent dse) {
395+ DragSourceListener dsl = listener;
396+ if (dsl != null) {
397+ dsl.dragExit(dse);
398+ }
399+ getDragSource().processDragExit(dse);
400+
401+ updateCurrentCursor(DnDConstants.ACTION_NONE, DnDConstants.ACTION_NONE, DEFAULT);
402+ }
403+
404+ /**
405+ * Calls <code>dropActionChanged</code> on the
406+ * <code>DragSourceListener</code>s registered with this
407+ * <code>DragSourceContext</code> and with the associated
408+ * <code>DragSource</code>, and passes them the specified
409+ * <code>DragSourceDragEvent</code>.
410+ *
411+ * @param dsde the <code>DragSourceDragEvent</code>
412+ */
413+ public void dropActionChanged(DragSourceDragEvent dsde) {
414+ DragSourceListener dsl = listener;
415+ if (dsl != null) {
416+ dsl.dropActionChanged(dsde);
417+ }
418+ getDragSource().processDropActionChanged(dsde);
419+
420+ updateCurrentCursor(getSourceActions(), dsde.getTargetActions(), CHANGED);
421+ }
422+
423+ /**
424+ * Calls <code>dragDropEnd</code> on the
425+ * <code>DragSourceListener</code>s registered with this
426+ * <code>DragSourceContext</code> and with the associated
427+ * <code>DragSource</code>, and passes them the specified
428+ * <code>DragSourceDropEvent</code>.
429+ *
430+ * @param dsde the <code>DragSourceDropEvent</code>
431+ */
432+ public void dragDropEnd(DragSourceDropEvent dsde) {
433+ DragSourceListener dsl = listener;
434+ if (dsl != null) {
435+ dsl.dragDropEnd(dsde);
436+ }
437+ getDragSource().processDragDropEnd(dsde);
438+ }
439+
440+ /**
441+ * Calls <code>dragMouseMoved</code> on the
442+ * <code>DragSourceMotionListener</code>s registered with the
443+ * <code>DragSource</code> associated with this
444+ * <code>DragSourceContext</code>, and them passes the specified
445+ * <code>DragSourceDragEvent</code>.
446+ *
447+ * @param dsde the <code>DragSourceDragEvent</code>
448+ * @since 1.4
449+ */
450+ public void dragMouseMoved(DragSourceDragEvent dsde) {
451+ getDragSource().processDragMouseMoved(dsde);
452+ }
453+
454+ /**
455+ * Returns the <code>Transferable</code> associated with
456+ * this <code>DragSourceContext</code>.
457+ *
458+ * @return the <code>Transferable</code>
459+ */
460+ public Transferable getTransferable() { return transferable; }
461+
462+ /**
463+ * If the default drag cursor behavior is active, this method
464+ * sets the default drag cursor for the specified actions
465+ * supported by the drag source, the drop target action,
466+ * and status, otherwise this method does nothing.
467+ *
468+ * @param sourceAct the actions supported by the drag source
469+ * @param targetAct the drop target action
470+ * @param status one of the fields <code>DEFAULT</code>,
471+ * <code>ENTER</code>, <code>OVER</code>,
472+ * <code>CHANGED</code>
473+ */
474+
475+ protected synchronized void updateCurrentCursor(int sourceAct, int targetAct, int status) {
476+
477+ // if the cursor has been previously set then dont do any defaults
478+ // processing.
479+
480+ if (useCustomCursor) {
481+ return;
482+ }
483+
484+ // do defaults processing
485+
486+ Cursor c = null;
487+
488+ switch (status) {
489+ default:
490+ targetAct = DnDConstants.ACTION_NONE;
491+ case ENTER:
492+ case OVER:
493+ case CHANGED:
494+ int ra = sourceAct & targetAct;
495+
496+ if (ra == DnDConstants.ACTION_NONE) { // no drop possible
497+ if ((sourceAct & DnDConstants.ACTION_LINK) == DnDConstants.ACTION_LINK)
498+ c = DragSource.DefaultLinkNoDrop;
499+ else if ((sourceAct & DnDConstants.ACTION_MOVE) == DnDConstants.ACTION_MOVE)
500+ c = DragSource.DefaultMoveNoDrop;
501+ else
502+ c = DragSource.DefaultCopyNoDrop;
503+ } else { // drop possible
504+ if ((ra & DnDConstants.ACTION_LINK) == DnDConstants.ACTION_LINK)
505+ c = DragSource.DefaultLinkDrop;
506+ else if ((ra & DnDConstants.ACTION_MOVE) == DnDConstants.ACTION_MOVE)
507+ c = DragSource.DefaultMoveDrop;
508+ else
509+ c = DragSource.DefaultCopyDrop;
510+ }
511+ }
512+
513+ setCursorImpl(c);
514+ }
515+
516+ private void setCursorImpl(Cursor c) {
517+ if (cursor == null || !cursor.equals(c)) {
518+ cursor = c;
519+ if (peer != null) peer.setCursor(cursor);
520+ }
521+ }
522+
523+ /**
524+ * Serializes this <code>DragSourceContext</code>. This method first
525+ * performs default serialization. Next, this object's
526+ * <code>Transferable</code> is written out if and only if it can be
527+ * serialized. If not, <code>null</code> is written instead. In this case,
528+ * a <code>DragSourceContext</code> created from the resulting deserialized
529+ * stream will contain a dummy <code>Transferable</code> which supports no
530+ * <code>DataFlavor</code>s. Finally, this object's
531+ * <code>DragSourceListener</code> is written out if and only if it can be
532+ * serialized. If not, <code>null</code> is written instead.
533+ *
534+ * @serialData The default serializable fields, in alphabetical order,
535+ * followed by either a <code>Transferable</code> instance, or
536+ * <code>null</code>, followed by either a
537+ * <code>DragSourceListener</code> instance, or
538+ * <code>null</code>.
539+ * @since 1.4
540+ */
541+ private void writeObject(ObjectOutputStream s) throws IOException {
542+ s.defaultWriteObject();
543+
544+ s.writeObject(SerializationTester.test(transferable)
545+ ? transferable : null);
546+ s.writeObject(SerializationTester.test(listener)
547+ ? listener : null);
548+ }
549+
550+ /**
551+ * Deserializes this <code>DragSourceContext</code>. This method first
552+ * performs default deserialization for all non-<code>transient</code>
553+ * fields. This object's <code>Transferable</code> and
554+ * <code>DragSourceListener</code> are then deserialized as well by using
555+ * the next two objects in the stream. If the resulting
556+ * <code>Transferable</code> is <code>null</code>, this object's
557+ * <code>Transferable</code> is set to a dummy <code>Transferable</code>
558+ * which supports no <code>DataFlavor</code>s.
559+ *
560+ * @since 1.4
561+ */
562+ private void readObject(ObjectInputStream s)
563+ throws ClassNotFoundException, IOException
564+ {
565+ s.defaultReadObject();
566+
567+ transferable = (Transferable)s.readObject();
568+ listener = (DragSourceListener)s.readObject();
569+
570+ // Implementation assumes 'transferable' is never null.
571+ if (transferable == null) {
572+ if (emptyTransferable == null) {
573+ emptyTransferable = new Transferable() {
574+ public DataFlavor[] getTransferDataFlavors() {
575+ return new DataFlavor[0];
576+ }
577+ public boolean isDataFlavorSupported(DataFlavor flavor)
578+ {
579+ return false;
580+ }
581+ public Object getTransferData(DataFlavor flavor)
582+ throws UnsupportedFlavorException
583+ {
584+ throw new UnsupportedFlavorException(flavor);
585+ }
586+ };
587+ }
588+ transferable = emptyTransferable;
589+ }
590+ }
591+
592+ private static Transferable emptyTransferable;
593+
594+ /*
595+ * fields
596+ */
597+
598+ private transient DragSourceContextPeer peer;
599+
600+ /**
601+ * The event which triggered the start of the drag.
602+ *
603+ * @serial
604+ */
605+ private DragGestureEvent trigger;
606+
607+ /**
608+ * The current drag cursor.
609+ *
610+ * @serial
611+ */
612+ private Cursor cursor;
613+
614+ private transient Transferable transferable;
615+
616+ private transient DragSourceListener listener;
617+
618+ /**
619+ * <code>true</code> if the custom drag cursor is used instead of the
620+ * default one.
621+ *
622+ * @serial
623+ */
624+ private boolean useCustomCursor;
625+
626+ /**
627+ * A bitwise mask of <code>DnDConstants</code> that represents the set of
628+ * drop actions supported by the drag source for the drag operation associated
629+ * with this <code>DragSourceContext.</code>
630+ *
631+ * @serial
632+ */
633+ private final int sourceActions;
634+}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t