Professional Documents
Culture Documents
How To Drag and Drop With Java 2, Part 2.2 - JavaWorld
How To Drag and Drop With Java 2, Part 2.2 - JavaWorld
NEWS
By Gene De Lisa
JavaWorld | Aug 20, 1999 1:00 AM PT
Page 2 of 3
Selecting the item under the pointer provides intuitive drag-under feedback. The pointer location can be retrieved from the
object by its method. This location can be turned into an index with the JList
method. If the returned index is , we need to clear the selection, since the pointer isn't over any item. Otherwise, we select the item
at the returned index. If the drop cannot take place at the selected index, we can change the background color to red and reset it to
the default selection color when the drop is OK. To undo the drag-under feedback, we can simply clear the selection.
Drag-over feedback
With the method, we can determine if the pointer is currently over an item or not. If the value returned from the
method is , the return value should be . The adapter will then set the no-drop cursor. One special case is
that if the model is empty, the method will always return , since there are no items over which the pointer can
be. Therefore, we should check to see if the model size is and return if it is.
The drop
The combination of our drag-over and drag-under feedback ensures that there will be an item selected when the drop occurs. Should
we insert the data before or after the item selected by our drag-under feedback?
One way to determine this is to make it a user preference. We need to remember which index we insert the data into, since it will be
used in the method.
The Transferable
Since the JList may contain many different kinds of data, we rely on the to provide the . The
JList only needs code to find the selected index and to get the from the model at that index. Here, too, we must
remember the selected index, since it will be needed in the case of a move operation.
Here's the code:
thisthis
returnthisthis
publicvoid
ifthislocal
ifthisthis
this
thisthis
JTree
For each of the D&D issues, we will now discuss possible solutions for a D&D-enabled JTree.
Drag-under feedback
You might want to expand the node under the pointer and select the node that the pointer is over. Display invalid feedback if this
node doesn't accept children.
Drag-over feedback
You can check to see if the node under the pointer allows children. If not, return from the method to show the nodrop cursor.
The drop
If the drop is local and the operation is to copy, you probably want to create a copy of the node rather than simply insert the node.
Otherwise, when either of the nodes (the original or the copy) is modified, the other will be as well. You might also want to make a
deep copy of the dropped node. The default method makes a shallow copy. You need to write your own deep-copy code. You
can do this with the and methods.
The Transferable
Create a object from the node under the current pointer location. Then save a reference to this node.
JTable
The JTable has many of the same issues as the JList.
The table is a view of the data in its model. If each table cell represents an object in the model, you may want to create a table in
which the user can drag and drop individual cells. If the table maps each object to a row and the table columns to the object's
attributes, you might want the user to be able to drag and drop a table row.
One frequent question that comes up in such situations is how to drop onto an empty table or a table with empty cells. For example,
the table could represent the innings in a baseball game. If the game is in progress, the table's later innings would be empty. (This is
more of a model question than a D&D issue.) One way to solve the problem is for the game model to start with nine default inning
objects. At the end of each inning the user can drop the new inning onto the table to replace the default one. A more efficient answer
for a situation with a large number of cells is to create a model that uses a sparse collection.
Drag-under feedback
You can select the cell or row under the pointer for drag-under feedback. To accomplish this, use methods and/or
to determine which row or cell the pointer is over.
Drag-over feedback
You may want to check the row and column at the current point and veto some cells. If you save the row and column that you used to
create the object, you can prevent dragging and dropping on the same cell. You can also retrieve the row and column
counts from the model. If the calculated row or column is greater than the model's row or column count, you may want to veto the
drop.
The drop
Does the drop replace the selected row or cell, or does it insert a new row or cell? If it isn't a local drop, it is possible that an edit is
in progress. Stop the editing, then either use the method to replace the selection or create a method in
the model that allows insertion before or after the selection.
Transferable
Retrieve the object from the model. Use the selected row and/or column to allow the model to determine how to make
the . If the table drags and drops rows, the selected column is ignored.
Composite components
Components such as the
and
are composed of several other components. In this section, we discuss the
issues involved with adding D&D capability to these components
work either. We need to make the glass pane invisible when a popup is visible in order to make popups work correctly. The
class can help to determine if a popup is visible:
MenuSelectionManager
MenuSelectionManager
MenuElement
If the selected path is greater than zero and the mouse event is a press (the instant in time when the user depresses the mouse
button, but has not yet released it) or a click (a press followed by a release), you need to set the glass pane as invisible. The selected
path can search for an instance of a
. If one is found, a can be installed that will make the glass pane
visible again when the popup becomes invisible.
JColorChooser
The glass pane technique doesn't work well with a
component. The object uses a
,
which doesn't handle mouse events correctly on tabs beyond the first one. The
may be modified to work correctly, but
that doesn't help with the
unless a new UI is installed. Also, since the glass pane forwards events to the children, the
children would interfere with the drag gesture.
The current solution is to write a new UI delegate with corrected
and D&D-enabled components. You can install your
D&D-enabled versions of the , , and
classes either by your own
class or by the 's method. It would be convenient if you were able
to set the , but that isn't currently possible. This
bug (actually it's a bug) is in the list
of outstanding bugs and will be fixed in a future release of the JDK.
InternalFrame
A common problem with the
is that D&D seems to work at first, but breaks down when an internal frame is selected.
The mystery is that when an internal frame is not selected, its glass pane becomes visible and catches events. This bug results from
the user's need to be able to select an inactive frame by pressing the mouse anywhere on the internal frame. This bug was
supposedly fixed in the JDK 1.2.2 release. In this release you were, in fact, able to drop onto the frame's children. However, the fix
seems to have introduced a selection-repaint bug where the previous selection isn't completely cleared during a drag.
One solution is to install another special glass pane that is a on each internal frame. This glass pane will forward
mouse events to the internal frame's child components. We can reuse our modified
for this. The only
modification to the dispatcher is to select the glass pane's internal frame on mouse-press events. A complication is that this glass
pane cannot dispatch D&D events (as it can ) since they are not subclasses.
JApplet
You can use D&D in an applet if your browser supports Java 2 or if you can use the Java 2 plugin. There are two steps to enable D&D
in an applet. First, the applet needs permissions granted in a policy file:
AWTPermission
AWTPermission
AWTPermission
AWTPermission
AWTPermission
To use this policy (in a file named ) with , use this command:
Djava
(Policy files have been discussed elsewhere in JavaWorld, see Resources for URLs.)
Second, s will not work if you create them in either the or methods. If you do create them in these
methods, you will be able to drag, but not drop.
Below is an example of a JApplet that contains D&D-enabled children. The method will create these
components and add them to the content pane. You will also want to check to see if this is the first time that the start message has
been received. Otherwise, you'd be adding many components!
publicvoid
//dothisonlythefirsttimestartiscalled
ThreadnewThreadthis
publicvoid
this
JPanelJPanel
If the JApplet itself is a drop site, you'll need to create the the same way -- in a separate thread. In addition, you'll need to
specify the content pane as the 's component:
publicvoid
this
JPanelJPanel
void
thisnewDropTargetAdapter
thisnewDropTargetthis
DnDConstants
this
true
PREVIOUS
NEXT
View Comments
View Comments
Copyright 1994 - 2016 JavaWorld, Inc. All rights reserved.