Users of a Lucy application may want to copy several objects from one layer to another. For instance, they may want to use a polyline that they have drawn with the drawing add-on as a trajectory for a flight plan. Lucy provides a data transfer manager that enables such an exchange. You can add functionality to this data manager so that objects of your data format can be exported to other layers as well, or to be able to import other data into your layers.

The Lucy data transfer mechanism is similar to the data transfer mechanism of Java Swing. For more information, see http://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html. Just like in Swing, the actual data is transferred using Transferable objects. Those transferables are created by so-called transfer handlers. However, in Swing those transfer handlers are TransferHandler objects, whereas in Lucy they are implementations of ALcyLayerSelectionTransferHandler. Furthermore, in Swing only one TransferHandler is used to create the Transferable: the one associated with the active JComponent. In Lucy, however, several ALcyLayerSelectionTransferHandler objects are used, more specifically, one per layer. The details of the object export and import are described in Overview.

To allow for the exchange of objects between your layers and other layers, you need to add one or more implementations of ALcyLayerSelectionTransferHandler to Lucy’s TLcyDataTransferManager. It is that implementation that will export the data in a format that other add-ons can understand, and that will import data from other add-ons if possible.

Overview

The data transfer in Lucy is initiated by the AWT/Swing data transfer system, for instance, if the user drags-and-drops objects, or if the user invokes a copy action or paste action. Under the right conditions, this could lead the AWT/Swing system to ask an ILcyMapComponent or ILcyLspMapComponent to export its data or import data.

Export

When the AWT/Swing transfer system asks an ILcyMapComponent or ILcyLspMapComponent to export its contents, that map component retrieves the appropriate ALcyLayerSelectionTransferHandler for each layer, and uses this handler to create a Transferable for that layer. This process is illustrated in Exporting Transferables. To retrieve the appropriate ALcyLayerSelectionTransferHandler for a layer, the map component loops over all ALcyLayerSelectionTransferHandler instances registered with Lucy’s TLcyDataTransferManager and determines for each handler whether it can export the selection in that layer using the getSourceActions method. A handler can export the given selection of the given layer if it returns a value other then ALcyLayerSelectionTransferHandler.NONE.

copypaste export
Figure 1. The selection of each layer is exported by one ALcyLayerSelectionTransferHandler. In this case, each created Transferable happens to support a common flavor.

Subsequently the map component will package all these individual Transferable objects into one single Transferable that can be handed off to AWT/Swing. This combination is illustrated in Clipboard transferable. The flavors supported by the combined Transferable are determined by the Transferable instances it combines. The supported flavors are the flavors that are commonly supported by each individual Transferable, plus the DataFlavor TLcyDataTransferManager.TRANSFERABLES_LIST_FLAVOR. This way, ALcyLayerSelectionTransferHandler objects can have access to all original information when they are asked to import this Transferable.

copypaste commonflavors
Figure 2. All transferables generated by the separate ALcyLayerSelectionTransferHandler instances are combined and put on the Clipboard. The flavors supported by this combined Transferable are the TLcyDataTransferManager.TRANSFERABLES_LIST_FLAVOR and the flavors commonly supported by all individual Transferable instances

Import

Before telling a component to import data, AWT/Swing first checks if the component can actually import the data. For this, the map component is given the available DataFlavor flavors. In turn, the map component looks for an ALcyLayerSelectionTransferHandler that can import data specified by those flavors into the layer that is selected in the layer control. If such an ALcyLayerSelectionTransferHandler is found, the map component tells AWT/Swing it can in fact import the data. The next step is actually importing the data. When it is importing, the map component gets the Transferable from AWT/Swing. Because of the nature of the AWT/Swing mechanism, this Transferable can be a transferable created by another map component, as described in Export, or it could be created somewhere else entirely. The ALcyLayerSelectionTransferHandler that previously said it could import the data is then given the transferable to process the data.