refactored awt.transferable out of the presenter

fixed copy/paste between instances
This commit is contained in:
bancika
2011-01-26 18:44:40 +00:00
parent f28dda37a6
commit 126d629cdc
6 changed files with 58 additions and 54 deletions
@@ -170,11 +170,11 @@ public interface IPlugInPort {
void mouseMoved(Point point, boolean ctrlDown, boolean shiftDown, boolean altDown); void mouseMoved(Point point, boolean ctrlDown, boolean shiftDown, boolean altDown);
/** /**
* Returns the current {@link ComponentSelection}. * Returns the current {@link ComponentTransferable}.
* *
* @return * @return
*/ */
ComponentSelection getSelectedComponents(); List<IDIYComponent<?>> getSelectedComponents();
/** /**
* Selects all components in the project. * Selects all components in the project.
@@ -16,7 +16,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.diylc.common.ComponentSelection;
import org.diylc.common.DrawOption; import org.diylc.common.DrawOption;
import org.diylc.common.EventType; import org.diylc.common.EventType;
import org.diylc.common.GridType; import org.diylc.common.GridType;
@@ -71,7 +70,7 @@ public class DrawingManager {
} }
public void drawProject(Graphics2D g2d, Project project, Set<DrawOption> drawOptions, public void drawProject(Graphics2D g2d, Project project, Set<DrawOption> drawOptions,
IComponentFiler filter, Rectangle selectionRect, ComponentSelection selectedComponents, IComponentFiler filter, Rectangle selectionRect, List<IDIYComponent<?>> selectedComponents,
Set<IDIYComponent<?>> lockedComponents, Set<IDIYComponent<?>> groupedComponents, Set<IDIYComponent<?>> lockedComponents, Set<IDIYComponent<?>> groupedComponents,
List<Point> controlPointSlot, IDIYComponent<?> componentSlot, boolean dragInProgress) { List<Point> controlPointSlot, IDIYComponent<?> componentSlot, boolean dragInProgress) {
if (project == null) { if (project == null) {
@@ -20,7 +20,6 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.diylc.common.ComponentSelection;
import org.diylc.common.ComponentType; import org.diylc.common.ComponentType;
import org.diylc.common.DrawOption; import org.diylc.common.DrawOption;
import org.diylc.common.EventType; import org.diylc.common.EventType;
@@ -54,6 +53,8 @@ public class Presenter implements IPlugInPort {
public static final String DEFAULTS_KEY_PREFIX = "default."; public static final String DEFAULTS_KEY_PREFIX = "default.";
public static final String METRIC_KEY = "metric"; public static final String METRIC_KEY = "metric";
public static final List<IDIYComponent<?>> EMPTY_SELECTION = Collections.emptyList();
public static final int ICON_SIZE = 32; public static final int ICON_SIZE = 32;
private Project currentProject; private Project currentProject;
@@ -61,7 +62,7 @@ public class Presenter implements IPlugInPort {
// Maps component class names to ComponentType objects. // Maps component class names to ComponentType objects.
private List<IPlugIn> plugIns; private List<IPlugIn> plugIns;
private ComponentSelection selectedComponents; private List<IDIYComponent<?>> selectedComponents;
// Maps components that have at least one dragged point to set of indices // Maps components that have at least one dragged point to set of indices
// that designate which of their control points are being dragged. // that designate which of their control points are being dragged.
private Map<IDIYComponent<?>, Set<Integer>> controlPointMap; private Map<IDIYComponent<?>, Set<Integer>> controlPointMap;
@@ -96,7 +97,7 @@ public class Presenter implements IPlugInPort {
this.view = view; this.view = view;
plugIns = new ArrayList<IPlugIn>(); plugIns = new ArrayList<IPlugIn>();
messageDispatcher = new MessageDispatcher<EventType>(true); messageDispatcher = new MessageDispatcher<EventType>(true);
selectedComponents = new ComponentSelection(); selectedComponents = new ArrayList<IDIYComponent<?>>();
lockedComponents = new HashSet<IDIYComponent<?>>(); lockedComponents = new HashSet<IDIYComponent<?>>();
currentProject = new Project(); currentProject = new Project();
cloner = new Cloner(); cloner = new Cloner();
@@ -178,7 +179,7 @@ public class Presenter implements IPlugInPort {
public void loadProject(Project project, boolean freshStart) { public void loadProject(Project project, boolean freshStart) {
LOG.info(String.format("loadProject(%s, %s)", project.getTitle(), freshStart)); LOG.info(String.format("loadProject(%s, %s)", project.getTitle(), freshStart));
this.currentProject = project; this.currentProject = project;
updateSelection(ComponentSelection.EMPTY_SELECTION); updateSelection(EMPTY_SELECTION);
messageDispatcher.dispatchMessage(EventType.PROJECT_LOADED, project, freshStart); messageDispatcher.dispatchMessage(EventType.PROJECT_LOADED, project, freshStart);
messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.REPAINT);
messageDispatcher.dispatchMessage(EventType.LAYER_STATE_CHANGED, currentProject messageDispatcher.dispatchMessage(EventType.LAYER_STATE_CHANGED, currentProject
@@ -355,7 +356,9 @@ public class Presenter implements IPlugInPort {
// messageDispatcher.dispatchMessage(EventType.SELECTION_SIZE_CHANGED, // messageDispatcher.dispatchMessage(EventType.SELECTION_SIZE_CHANGED,
// calculateSelectionDimension()); // calculateSelectionDimension());
messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.REPAINT);
updateSelection(ComponentSelection.of(component)); List<IDIYComponent<?>> newSelection = new ArrayList<IDIYComponent<?>>();
newSelection.add(component);
updateSelection(newSelection);
} catch (Exception e) { } catch (Exception e) {
LOG.error("Error instatiating component of type: " LOG.error("Error instatiating component of type: "
+ componentTypeSlot.getInstanceClass().getName(), e); + componentTypeSlot.getInstanceClass().getName(), e);
@@ -385,8 +388,11 @@ public class Presenter implements IPlugInPort {
componentSlot.setControlPoint(scaledPoint, 1); componentSlot.setControlPoint(scaledPoint, 1);
addComponent(componentSlot, componentTypeSlot); addComponent(componentSlot, componentTypeSlot);
// Select the new component if it's not locked. // Select the new component if it's not locked.
updateSelection(isComponentLocked(componentSlot) ? ComponentSelection.EMPTY_SELECTION List<IDIYComponent<?>> newSelection = new ArrayList<IDIYComponent<?>>();
: ComponentSelection.of(componentSlot)); if (!isComponentLocked(componentSlot)) {
newSelection.add(componentSlot);
}
updateSelection(newSelection);
messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.REPAINT);
setNewComponentTypeSlot(null); setNewComponentTypeSlot(null);
} }
@@ -401,7 +407,8 @@ public class Presenter implements IPlugInPort {
projectFileManager.notifyFileChange(); projectFileManager.notifyFileChange();
} }
} else { } else {
ComponentSelection newSelection = new ComponentSelection(selectedComponents); List<IDIYComponent<?>> newSelection = new ArrayList<IDIYComponent<?>>(
selectedComponents);
List<IDIYComponent<?>> components = findComponentsAt(scaledPoint); List<IDIYComponent<?>> components = findComponentsAt(scaledPoint);
// If there's nothing under mouse cursor deselect all. // If there's nothing under mouse cursor deselect all.
if (components.isEmpty()) { if (components.isEmpty()) {
@@ -445,8 +452,8 @@ public class Presenter implements IPlugInPort {
refresh = instantiationManager.updatePointByPoint(scaledPoint); refresh = instantiationManager.updatePointByPoint(scaledPoint);
break; break;
case SINGLE_CLICK: case SINGLE_CLICK:
refresh = instantiationManager.updateSingleClick(scaledPoint, snapToGrid, currentProject refresh = instantiationManager.updateSingleClick(scaledPoint, snapToGrid,
.getGridSpacing()); currentProject.getGridSpacing());
break; break;
} }
if (refresh) { if (refresh) {
@@ -496,14 +503,14 @@ public class Presenter implements IPlugInPort {
} }
@Override @Override
public ComponentSelection getSelectedComponents() { public List<IDIYComponent<?>> getSelectedComponents() {
return new ComponentSelection(selectedComponents); return selectedComponents;
} }
@Override @Override
public void selectAll() { public void selectAll() {
LOG.info("selectAll()"); LOG.info("selectAll()");
updateSelection(new ComponentSelection(currentProject.getComponents())); updateSelection(new ArrayList<IDIYComponent<?>>(currentProject.getComponents()));
// messageDispatcher.dispatchMessage(EventType.SELECTION_CHANGED, // messageDispatcher.dispatchMessage(EventType.SELECTION_CHANGED,
// selectedComponents); // selectedComponents);
// messageDispatcher.dispatchMessage(EventType.SELECTION_SIZE_CHANGED, // messageDispatcher.dispatchMessage(EventType.SELECTION_SIZE_CHANGED,
@@ -531,7 +538,7 @@ public class Presenter implements IPlugInPort {
List<IDIYComponent<?>> components = findComponentsAt(scaledPoint); List<IDIYComponent<?>> components = findComponentsAt(scaledPoint);
if (!controlPointMap.isEmpty()) { if (!controlPointMap.isEmpty()) {
// If we're dragging control points reset selection. // If we're dragging control points reset selection.
updateSelection(new ComponentSelection(controlPointMap.keySet())); updateSelection(new ArrayList<IDIYComponent<?>>(controlPointMap.keySet()));
// messageDispatcher.dispatchMessage(EventType.SELECTION_CHANGED, // messageDispatcher.dispatchMessage(EventType.SELECTION_CHANGED,
// selectedComponents); // selectedComponents);
// messageDispatcher.dispatchMessage(EventType.SELECTION_SIZE_CHANGED, // messageDispatcher.dispatchMessage(EventType.SELECTION_SIZE_CHANGED,
@@ -539,7 +546,7 @@ public class Presenter implements IPlugInPort {
messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.REPAINT);
} else if (components.isEmpty()) { } else if (components.isEmpty()) {
// If there are no components are under the cursor, reset selection. // If there are no components are under the cursor, reset selection.
updateSelection(ComponentSelection.EMPTY_SELECTION); updateSelection(EMPTY_SELECTION);
// messageDispatcher.dispatchMessage(EventType.SELECTION_CHANGED, // messageDispatcher.dispatchMessage(EventType.SELECTION_CHANGED,
// selectedComponents); // selectedComponents);
// messageDispatcher.dispatchMessage(EventType.SELECTION_SIZE_CHANGED, // messageDispatcher.dispatchMessage(EventType.SELECTION_SIZE_CHANGED,
@@ -551,7 +558,7 @@ public class Presenter implements IPlugInPort {
// If the component under the cursor is not already selected, make // If the component under the cursor is not already selected, make
// it into the only selected component. // it into the only selected component.
if (!selectedComponents.contains(component)) { if (!selectedComponents.contains(component)) {
updateSelection(new ComponentSelection(findAllGroupedComponents(component))); updateSelection(new ArrayList<IDIYComponent<?>>(findAllGroupedComponents(component)));
// messageDispatcher.dispatchMessage(EventType.SELECTION_CHANGED, // messageDispatcher.dispatchMessage(EventType.SELECTION_CHANGED,
// selectedComponents); // selectedComponents);
// messageDispatcher.dispatchMessage(EventType.SELECTION_SIZE_CHANGED, // messageDispatcher.dispatchMessage(EventType.SELECTION_SIZE_CHANGED,
@@ -755,7 +762,7 @@ public class Presenter implements IPlugInPort {
if (scaledPoint != null) { if (scaledPoint != null) {
this.selectionRect = Utils.createRectangle(scaledPoint, previousDragPoint); this.selectionRect = Utils.createRectangle(scaledPoint, previousDragPoint);
} }
ComponentSelection newSelection = new ComponentSelection(); List<IDIYComponent<?>> newSelection = new ArrayList<IDIYComponent<?>>();
for (IDIYComponent<?> component : currentProject.getComponents()) { for (IDIYComponent<?> component : currentProject.getComponents()) {
if (!isComponentLocked(component)) { if (!isComponentLocked(component)) {
Area area = drawingManager.getComponentArea(component); Area area = drawingManager.getComponentArea(component);
@@ -802,7 +809,7 @@ public class Presenter implements IPlugInPort {
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, cloner messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, cloner
.deepClone(currentProject), "Add"); .deepClone(currentProject), "Add");
projectFileManager.notifyFileChange(); projectFileManager.notifyFileChange();
updateSelection(new ComponentSelection(components)); updateSelection(new ArrayList<IDIYComponent<?>>(components));
messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.REPAINT);
} }
@@ -824,7 +831,7 @@ public class Presenter implements IPlugInPort {
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, cloner messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, cloner
.deepClone(currentProject), "Delete"); .deepClone(currentProject), "Delete");
projectFileManager.notifyFileChange(); projectFileManager.notifyFileChange();
updateSelection(ComponentSelection.EMPTY_SELECTION); updateSelection(EMPTY_SELECTION);
messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.REPAINT);
} }
@@ -890,20 +897,20 @@ public class Presenter implements IPlugInPort {
} else { } else {
currentProject.getLockedLayers().remove(layerZOrder); currentProject.getLockedLayers().remove(layerZOrder);
} }
updateSelection(ComponentSelection.EMPTY_SELECTION); updateSelection(EMPTY_SELECTION);
messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.REPAINT);
messageDispatcher.dispatchMessage(EventType.LAYER_STATE_CHANGED, currentProject messageDispatcher.dispatchMessage(EventType.LAYER_STATE_CHANGED, currentProject
.getLockedLayers()); .getLockedLayers());
} }
/** /**
* Updates the selection with the specified {@link ComponentSelection}. * Updates the selection with the specified {@link ComponentTransferable}.
* Also, updates control point map with all components that are stuck to the * Also, updates control point map with all components that are stuck to the
* newly selected components. * newly selected components.
* *
* @param newSelection * @param newSelection
*/ */
private void updateSelection(ComponentSelection newSelection) { private void updateSelection(List<IDIYComponent<?>> newSelection) {
this.selectedComponents = newSelection; this.selectedComponents = newSelection;
Map<IDIYComponent<?>, Set<Integer>> controlPointMap = new HashMap<IDIYComponent<?>, Set<Integer>>(); Map<IDIYComponent<?>, Set<Integer>> controlPointMap = new HashMap<IDIYComponent<?>, Set<Integer>>();
for (IDIYComponent<?> component : selectedComponents) { for (IDIYComponent<?> component : selectedComponents) {
@@ -1090,7 +1097,7 @@ public class Presenter implements IPlugInPort {
try { try {
instantiationManager.setComponentTypeSlot(componentType, currentProject); instantiationManager.setComponentTypeSlot(componentType, currentProject);
if (componentType != null) { if (componentType != null) {
updateSelection(ComponentSelection.EMPTY_SELECTION); updateSelection(EMPTY_SELECTION);
} }
messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.REPAINT);
// messageDispatcher.dispatchMessage(EventType.SELECTION_CHANGED, // messageDispatcher.dispatchMessage(EventType.SELECTION_CHANGED,
@@ -1,4 +1,4 @@
package org.diylc.common; package org.diylc.swing.plugins.clipboard;
import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable; import java.awt.datatransfer.Transferable;
@@ -10,33 +10,24 @@ import java.util.List;
import org.diylc.core.IDIYComponent; import org.diylc.core.IDIYComponent;
/** /**
* Represents component selection as a {@link List} of * Represents component selection as a {@link List} of {@link IDIYComponent}
* {@link IDIYComponent} objects. Implements {@link Transferable}, so it is * objects. Implements {@link Transferable}, so it is suitable for clipboard
* suitable for clipboard usage. * usage.
* *
* @author Branislav Stojkovic * @author Branislav Stojkovic
*/ */
public class ComponentSelection extends ArrayList<IDIYComponent<?>> implements Transferable { public class ComponentTransferable extends ArrayList<IDIYComponent<?>> implements Transferable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public static final DataFlavor listFlavor = new DataFlavor(List.class, "Java List"); public static final DataFlavor listFlavor = new DataFlavor(ComponentTransferable.class, "application/diylc");
public static final ComponentSelection EMPTY_SELECTION = new ComponentSelection();
public static ComponentSelection of(IDIYComponent<?> component) {
ComponentSelection selection = new ComponentSelection();
selection.add(component);
return selection;
}
public ComponentSelection() { public ComponentTransferable() {
super(); super();
} }
public ComponentSelection(Collection<IDIYComponent<?>> selectedComponents) { public ComponentTransferable(Collection<IDIYComponent<?>> selectedComponents) {
super(selectedComponents); super(selectedComponents);
} }
@@ -15,7 +15,6 @@ import javax.swing.AbstractAction;
import javax.swing.KeyStroke; import javax.swing.KeyStroke;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.diylc.common.ComponentSelection;
import org.diylc.common.EventType; import org.diylc.common.EventType;
import org.diylc.common.IPlugIn; import org.diylc.common.IPlugIn;
import org.diylc.common.IPlugInPort; import org.diylc.common.IPlugInPort;
@@ -42,13 +41,21 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner {
private Clipboard clipboard; private Clipboard clipboard;
private Cloner cloner; private Cloner cloner;
// private CutAction cutAction; // private CutAction cutAction;
private CopyAction copyAction; private CopyAction copyAction;
private PasteAction pasteAction; private PasteAction pasteAction;
private UndoHandler<Project> undoHandler; private UndoHandler<Project> undoHandler;
public EditMenuPlugin(ISwingUI swingUI) { public EditMenuPlugin(ISwingUI swingUI) {
SecurityManager securityManager = System.getSecurityManager();
if (securityManager != null) {
try {
securityManager.checkSystemClipboardAccess();
} catch (Exception e) {
e.printStackTrace();
}
}
clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
cloner = new Cloner(); cloner = new Cloner();
undoHandler = new UndoHandler<Project>(new IUndoListener<Project>() { undoHandler = new UndoHandler<Project>(new IUndoListener<Project>() {
@@ -65,7 +72,7 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner {
refreshActions(); refreshActions();
} }
}); });
swingUI.injectMenuAction(undoHandler.getUndoAction(), EDIT_TITLE); swingUI.injectMenuAction(undoHandler.getUndoAction(), EDIT_TITLE);
swingUI.injectMenuAction(undoHandler.getRedoAction(), EDIT_TITLE); swingUI.injectMenuAction(undoHandler.getRedoAction(), EDIT_TITLE);
swingUI.injectMenuAction(null, EDIT_TITLE); swingUI.injectMenuAction(null, EDIT_TITLE);
@@ -112,8 +119,9 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner {
boolean enabled = !plugInPort.getSelectedComponents().isEmpty(); boolean enabled = !plugInPort.getSelectedComponents().isEmpty();
// cutAction.setEnabled(enabled); // cutAction.setEnabled(enabled);
copyAction.setEnabled(enabled); copyAction.setEnabled(enabled);
try { try {
pasteAction.setEnabled(clipboard.isDataFlavorAvailable(ComponentSelection.listFlavor)); pasteAction.setEnabled(clipboard
.isDataFlavorAvailable(ComponentTransferable.listFlavor));
} catch (Exception e) { } catch (Exception e) {
pasteAction.setEnabled(false); pasteAction.setEnabled(false);
} }
@@ -152,8 +160,8 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
LOG.info("Copy triggered"); LOG.info("Copy triggered");
clipboard.setContents(cloner.deepClone(plugInPort.getSelectedComponents()), clipboard.setContents(new ComponentTransferable(cloner.deepClone(plugInPort
EditMenuPlugin.this); .getSelectedComponents())), EditMenuPlugin.this);
} }
} }
@@ -175,7 +183,7 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner {
LOG.info("Paste triggered"); LOG.info("Paste triggered");
try { try {
List<IDIYComponent<?>> components = (List<IDIYComponent<?>>) clipboard List<IDIYComponent<?>> components = (List<IDIYComponent<?>>) clipboard
.getData(ComponentSelection.listFlavor); .getData(ComponentTransferable.listFlavor);
plugInPort.pasteComponents(cloner.deepClone(components)); plugInPort.pasteComponents(cloner.deepClone(components));
} catch (Exception ex) { } catch (Exception ex) {
LOG.error("Coule not paste.", ex); LOG.error("Coule not paste.", ex);
@@ -28,7 +28,6 @@ import javax.swing.SwingUtilities;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.diylc.common.BadPositionException; import org.diylc.common.BadPositionException;
import org.diylc.common.ComponentSelection;
import org.diylc.common.ComponentType; import org.diylc.common.ComponentType;
import org.diylc.common.EventType; import org.diylc.common.EventType;
import org.diylc.common.IPlugIn; import org.diylc.common.IPlugIn;
@@ -217,7 +216,7 @@ public class StatusBar extends JPanel implements IPlugIn {
} }
break; break;
case SELECTION_CHANGED: case SELECTION_CHANGED:
ComponentSelection selection = (ComponentSelection) params[0]; List<IDIYComponent<?>> selection = (List<IDIYComponent<?>>) params[0];
Collection<IDIYComponent<?>> stuckComponents = (Collection<IDIYComponent<?>>) params[1]; Collection<IDIYComponent<?>> stuckComponents = (Collection<IDIYComponent<?>>) params[1];
Collection<String> componentNames = new HashSet<String>(); Collection<String> componentNames = new HashSet<String>();
for (IDIYComponent<?> component : selection) { for (IDIYComponent<?> component : selection) {