Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* PlanTransferHandler.java 12 sept. 2006
*
* Sweet Home 3D, Copyright (c) 2006 Emmanuel PUYBARET / eTeks
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.eteks.sweethome3d.swing;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.SwingUtilities;
import com.eteks.sweethome3d.model.Home;
import com.eteks.sweethome3d.model.Level;
import com.eteks.sweethome3d.model.Selectable;
import com.eteks.sweethome3d.viewcontroller.ContentManager;
import com.eteks.sweethome3d.viewcontroller.HomeController;
import com.eteks.sweethome3d.viewcontroller.View;
/**
* Plan transfer handler.
* @author Emmanuel Puybaret
*/
public class PlanTransferHandler extends LocatedTransferHandler {
private final Home home;
private final ContentManager contentManager;
private final HomeController homeController;
private List copiedItems;
private BufferedImage copiedImage;
private boolean isDragging;
private WindowAdapter windowDeactivationListener;
/**
* Creates a handler able to transfer furniture and walls in plan.
*/
public PlanTransferHandler(Home home, ContentManager contentManager,
HomeController homeController) {
this.home = home;
this.contentManager = contentManager;
this.homeController = homeController;
}
/**
* Returns COPY_OR_MOVE.
*/
@Override
public int getSourceActions(JComponent source) {
return COPY_OR_MOVE;
}
/**
* Returns a transferable object that contains a copy of the selected items in home
* and an image of the selected items.
*/
@Override
protected Transferable createTransferable(final JComponent source) {
this.copiedItems = this.home.getSelectedItems();
final Transferable transferable = new HomeTransferableList(this.copiedItems);
if (source instanceof PlanComponent) {
// Create an image that contains only selected items
this.copiedImage = ((PlanComponent)source).getClipboardImage();
// Create a transferable that contains copied items and an image
return new Transferable () {
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
if (DataFlavor.imageFlavor.equals(flavor)) {
return copiedImage;
} else {
return transferable.getTransferData(flavor);
}
}
public DataFlavor [] getTransferDataFlavors() {
ArrayList dataFlavors =
new ArrayList(Arrays.asList(transferable.getTransferDataFlavors()));
dataFlavors.add(DataFlavor.imageFlavor);
return dataFlavors.toArray(new DataFlavor [dataFlavors.size()]);
}
public boolean isDataFlavorSupported(DataFlavor flavor) {
return transferable.isDataFlavorSupported(flavor)
|| DataFlavor.imageFlavor.equals(flavor);
}
};
} else {
return transferable;
}
}
/**
* Removes the copied element once moved.
*/
@Override
protected void exportDone(JComponent source, Transferable data, int action) {
if (action == MOVE) {
this.homeController.cut(this.copiedItems);
}
this.copiedItems = null;
this.copiedImage = null;
this.homeController.enablePasteAction();
}
/**
* Returns true if flavors contains
* {@link HomeTransferableList#HOME_FLAVOR HOME_FLAVOR} flavor
* or DataFlavor.javaFileListFlavor flavor.
*/
@Override
protected boolean canImportFlavor(DataFlavor [] flavors) {
Level selectedLevel = this.home.getSelectedLevel();
List flavorList = Arrays.asList(flavors);
return (selectedLevel == null || selectedLevel.isViewable())
&& (flavorList.contains(HomeTransferableList.HOME_FLAVOR)
|| flavorList.contains(DataFlavor.javaFileListFlavor));
}
/**
* Notifies home controller that a drag operation started if
* transferable data contains {@link HomeTransferableList#HOME_FLAVOR HOME_FLAVOR}
* flavor and destination is a plan.
*/
@Override
protected void dragEntered(final JComponent destination, Transferable transferable, int dragAction) {
if (transferable.isDataFlavorSupported(HomeTransferableList.HOME_FLAVOR)
&& destination instanceof PlanComponent
&& this.homeController.getPlanController() != null) {
try {
List transferedItems =
(List)transferable.getTransferData(HomeTransferableList.HOME_FLAVOR);
Point2D dropLocation = getDropModelLocation(destination);
this.homeController.getPlanController().startDraggedItems(transferedItems,
(float)dropLocation.getX(), (float)dropLocation.getY());
// Add a window deactivation listener to stop drag and drop in case current window is deactivated
// because a dialog was opened while dragging
this.windowDeactivationListener = new WindowAdapter() {
@Override
public void windowDeactivated(WindowEvent e) {
dragExited(destination);
}
};
SwingUtilities.getWindowAncestor(destination).addWindowListener(this.windowDeactivationListener);
this.isDragging = true;
} catch (UnsupportedFlavorException ex) {
throw new RuntimeException("Can't import", ex);
} catch (IOException ex) {
throw new RuntimeException("Can't access to data", ex);
}
}
}
/**
* Called when transferable data moved in destination component
* during a drag and drop operation. Subclasses should override this method if they are
* interested by this event.
*/
@Override
protected void dragMoved(JComponent destination, Transferable transferable, int dragAction) {
if (transferable.isDataFlavorSupported(HomeTransferableList.HOME_FLAVOR)
&& destination instanceof PlanComponent
&& this.homeController.getPlanController() != null) {
Point2D dropLocation = getDropModelLocation(destination);
this.homeController.getPlanController().moveMouse(
(float)dropLocation.getX(), (float)dropLocation.getY());
}
}
/**
* Called once the cursor left destination component during a drag and drop operation.
* Subclasses should override this method if they are interested by this event.
*/
@Override
protected void dragExited(JComponent destination) {
if (this.isDragging) {
SwingUtilities.getWindowAncestor(destination).removeWindowListener(this.windowDeactivationListener);
this.homeController.getPlanController().stopDraggedItems();
this.isDragging = false;
}
}
/**
* Adds items contained in transferable to home.
*/
@Override
public boolean importData(JComponent destination, Transferable transferable) {
if (canImportFlavor(transferable.getTransferDataFlavors())) {
try {
if (this.isDragging) {
dragExited(destination);
}
List flavorList = Arrays.asList(transferable.getTransferDataFlavors());
if (flavorList.contains(HomeTransferableList.HOME_FLAVOR)) {
return importHomeTransferableList(destination,
(List)transferable.getTransferData(HomeTransferableList.HOME_FLAVOR));
} else {
return importFileList(destination,
(List)transferable.getTransferData(DataFlavor.javaFileListFlavor));
}
} catch (UnsupportedFlavorException ex) {
throw new RuntimeException("Can't import", ex);
} catch (IOException ex) {
throw new RuntimeException("Can't access to data", ex);
}
} else {
return false;
}
}
private boolean importHomeTransferableList(final JComponent destination,
final List transferedItems) {
if (isDrop()) {
Point2D dropLocation = getDropModelLocation(destination);
if (destination instanceof View) {
this.homeController.drop(transferedItems, this.homeController.getPlanController().getView(),
(float)dropLocation.getX(), (float)dropLocation.getY());
} else {
this.homeController.drop(transferedItems,
(float)dropLocation.getX(), (float)dropLocation.getY());
}
} else {
this.homeController.paste(transferedItems);
}
return true;
}
private boolean importFileList(final JComponent destination, List files) {
final Point2D dropLocation = isDrop()
? getDropModelLocation(destination)
: new Point2D.Float();
final List importableModels = getModelContents(files, contentManager);
EventQueue.invokeLater(new Runnable() {
public void run() {
homeController.dropFiles(importableModels,
(float)dropLocation.getX(), (float)dropLocation.getY());
}
});
return !importableModels.isEmpty();
}
/**
* Returns the drop location converted in model coordinates space.
*/
private Point2D getDropModelLocation(JComponent destination) {
float x = 0;
float y = 0;
if (destination instanceof PlanComponent) {
PlanComponent planView = (PlanComponent)destination;
Point dropLocation = getDropLocation();
SwingUtilities.convertPointFromScreen(dropLocation, planView);
x = planView.convertXPixelToModel(dropLocation.x);
y = planView.convertYPixelToModel(dropLocation.y);
}
return new Point2D.Float(x, y);
}
}