diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml new file mode 100644 index 000000000..6205bf836 --- /dev/null +++ b/.github/workflows/maven.yml @@ -0,0 +1,40 @@ +name: Java CI with Maven + +on: + push: + branches: [ "develop" ] + pull_request: + branches: [ "develop" ] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up JDK 23 + uses: actions/setup-java@v4 + with: + java-version: '23' + distribution: 'temurin' + cache: maven + - name: Configure GitHub Packages credentials + run: | + mkdir -p ~/.m2 + cat > ~/.m2/settings.xml < + + + github + ${GITHUB_ACTOR} + ${GITHUB_TOKEN} + + + + EOF + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_ACTOR: ${{ github.actor }} + - name: Build entire project with Maven + run: mvn -B clean install --file pom.xml + - name: Run tests + run: mvn test --file pom.xml diff --git a/.maven-settings.xml b/.maven-settings.xml new file mode 100644 index 000000000..5370d863d --- /dev/null +++ b/.maven-settings.xml @@ -0,0 +1,9 @@ + + + + github + ${{ secrets.GITHUB_ACTOR }} + ${{ secrets.GITHUB_TOKEN }} + + + diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..2b3fe865d --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,23 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "type": "java", + "name": "Debug JHotDraw Draw Sample", + "request": "launch", + "mainClass": "org.jhotdraw.samples.draw.Main", + "projectName": "jhotdraw-samples-misc", + "classPaths": [ + "${workspaceFolder}/jhotdraw-samples/jhotdraw-samples-misc/target/classes", + "${workspaceFolder}/jhotdraw-core/target/classes", + "${workspaceFolder}/jhotdraw-actions/target/classes", + "${workspaceFolder}/jhotdraw-app/target/classes", + "${workspaceFolder}/jhotdraw-api/target/classes", + "${workspaceFolder}/jhotdraw-gui/target/classes", + "${workspaceFolder}/jhotdraw-utils/target/classes", + "${workspaceFolder}/jhotdraw-xml/target/classes", + "${workspaceFolder}/jhotdraw-datatransfer/target/classes" + ] + } + ] +} diff --git a/README.md b/README.md deleted file mode 100644 index d3da3d6ae..000000000 --- a/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# jhotdraw - -* maven build process -* restructured project layout - * introduced submodules - -## License - -* LGPL V2.1 -* Creative Commons Attribution 2.5 License - -## History - -This is a fork of jhotdraw from http://sourceforge.net/projects/jhotdraw. diff --git a/jhotdraw-core/src/main/java/org/jhotdraw/draw/DefaultDrawingViewTransferHandler.java b/jhotdraw-core/src/main/java/org/jhotdraw/draw/DefaultDrawingViewTransferHandler.java index 316e335a7..c6bcaf28e 100644 --- a/jhotdraw-core/src/main/java/org/jhotdraw/draw/DefaultDrawingViewTransferHandler.java +++ b/jhotdraw-core/src/main/java/org/jhotdraw/draw/DefaultDrawingViewTransferHandler.java @@ -98,43 +98,9 @@ protected boolean importData(final JComponent comp, Transferable t, final HashSe SearchLoop: for (InputFormat format : drawing.getInputFormats()) { for (DataFlavor flavor : transferFlavors) { if (format.isDataFlavorSupported(flavor)) { - LinkedList
existingFigures = new LinkedList<>(drawing.getChildren()); - try { - format.read(t, drawing, false); - final LinkedList
importedFigures = new LinkedList<>(drawing. - getChildren()); - importedFigures.removeAll(existingFigures); - view.clearSelection(); - view.addToSelection(importedFigures); - transferFigures.addAll(importedFigures); - moveToDropPoint(comp, transferFigures, dropPoint); - drawing.fireUndoableEditHappened(new AbstractUndoableEdit() { - private static final long serialVersionUID = 1L; - - @Override - public String getPresentationName() { - ResourceBundleUtil labels = ResourceBundleUtil.getBundle( - "org.jhotdraw.draw.Labels"); - return labels.getString("edit.paste.text"); - } - - @Override - public void undo() throws CannotUndoException { - super.undo(); - drawing.removeAll(importedFigures); - } - - @Override - public void redo() throws CannotRedoException { - super.redo(); - drawing.addAll(importedFigures); - } - }); + if (importTransferData(comp, t, transferFigures, dropPoint, view, drawing, format)) { retValue = true; break SearchLoop; - } catch (IOException e) { - e.printStackTrace(); - // failed to read transferalbe, try with next InputFormat } } } @@ -144,43 +110,9 @@ public void redo() throws CannotRedoException { SearchLoop: for (DataFlavor flavor : transferFlavors) { for (InputFormat format : drawing.getInputFormats()) { if (format.isDataFlavorSupported(flavor)) { - LinkedList
existingFigures = new LinkedList<>(drawing.getChildren()); - try { - format.read(t, drawing, false); - final LinkedList
importedFigures = new LinkedList<>(drawing. - getChildren()); - importedFigures.removeAll(existingFigures); - view.clearSelection(); - view.addToSelection(importedFigures); - transferFigures.addAll(importedFigures); - moveToDropPoint(comp, transferFigures, dropPoint); - drawing.fireUndoableEditHappened(new AbstractUndoableEdit() { - private static final long serialVersionUID = 1L; - - @Override - public String getPresentationName() { - ResourceBundleUtil labels = ResourceBundleUtil.getBundle( - "org.jhotdraw.draw.Labels"); - return labels.getString("edit.paste.text"); - } - - @Override - public void undo() throws CannotUndoException { - super.undo(); - drawing.removeAll(importedFigures); - } - - @Override - public void redo() throws CannotRedoException { - super.redo(); - drawing.addAll(importedFigures); - } - }); + if (importTransferData(comp, t, transferFigures, dropPoint, view, drawing, format)) { retValue = true; break SearchLoop; - } catch (IOException e) { - e.printStackTrace(); - // failed to read transferalbe, try with next InputFormat } } } @@ -218,28 +150,7 @@ protected void done() { view.addToSelection(importedFigures); transferFigures.addAll(importedFigures); moveToDropPoint(comp, transferFigures, dropPoint); - drawing.fireUndoableEditHappened(new AbstractUndoableEdit() { - private static final long serialVersionUID = 1L; - - @Override - public String getPresentationName() { - ResourceBundleUtil labels = ResourceBundleUtil.getBundle( - "org.jhotdraw.draw.Labels"); - return labels.getString("edit.paste.text"); - } - - @Override - public void undo() throws CannotUndoException { - super.undo(); - drawing.removeAll(importedFigures); - } - - @Override - public void redo() throws CannotRedoException { - super.redo(); - drawing.addAll(importedFigures); - } - }); + firePasteUndoableEdit(drawing, importedFigures); } view.getEditor().setEnabled(true); @@ -260,10 +171,54 @@ public void redo() throws CannotRedoException { return retValue; } + private boolean importTransferData(final JComponent comp, Transferable t, final HashSet
transferFigures, + final Point dropPoint, final DrawingView view, final Drawing drawing, + InputFormat format) throws UnsupportedFlavorException { + LinkedList
existingFigures = new LinkedList<>(drawing.getChildren()); + try { + format.read(t, drawing, false); + final LinkedList
importedFigures = new LinkedList<>(drawing.getChildren()); + importedFigures.removeAll(existingFigures); + view.clearSelection(); + view.addToSelection(importedFigures); + transferFigures.addAll(importedFigures); + moveToDropPoint(comp, transferFigures, dropPoint); + firePasteUndoableEdit(drawing, importedFigures); + return true; + } catch (IOException e) { + e.printStackTrace(); + // Failed to read transferable; try with the next InputFormat. + return false; + } + } + + private void firePasteUndoableEdit(final Drawing drawing, final LinkedList
importedFigures) { + drawing.fireUndoableEditHappened(new AbstractUndoableEdit() { + private static final long serialVersionUID = 1L; + + @Override + public String getPresentationName() { + ResourceBundleUtil labels = ResourceBundleUtil.getBundle("org.jhotdraw.draw.Labels"); + return labels.getString("edit.paste.text"); + } + + @Override + public void undo() throws CannotUndoException { + super.undo(); + drawing.removeAll(importedFigures); + } + + @Override + public void redo() throws CannotRedoException { + super.redo(); + drawing.addAll(importedFigures); + } + }); + } + protected void moveToDropPoint(JComponent component, HashSet
transferFigures, Point dropPoint) { if (dropPoint == null) { - // This ugly code sequence is needed to ensure that the drawing view - // repaints the area which contains the dropped figures. + // Ensure that the drawing view repaints the area containing the dropped figures. for (Figure fig : transferFigures) { fig.willChange(); fig.changed(); @@ -493,10 +448,6 @@ public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) { return retValue; } - private void getDrawing() { - throw new UnsupportedOperationException("Not yet implemented"); - } - /** * This is the default drag handler for drag and drop operations that use * the diff --git a/jhotdraw-datatransfer/src/main/java/org/jhotdraw/datatransfer/CompositeTransferable.java b/jhotdraw-datatransfer/src/main/java/org/jhotdraw/datatransfer/CompositeTransferable.java index 41a7388e3..288fc77b7 100644 --- a/jhotdraw-datatransfer/src/main/java/org/jhotdraw/datatransfer/CompositeTransferable.java +++ b/jhotdraw-datatransfer/src/main/java/org/jhotdraw/datatransfer/CompositeTransferable.java @@ -12,14 +12,14 @@ import java.util.*; /** - * ComoositeTransferable. + * CompositeTransferable. * * @author Werner Randelshofer */ public class CompositeTransferable implements Transferable, ClipboardOwner { - private HashMap transferables = new HashMap<>(); - private LinkedList flavors = new LinkedList<>(); + private final HashMap transferables = new HashMap<>(); + private final LinkedList flavors = new LinkedList<>(); /** * Creates a new instance of CompositeTransferable @@ -74,7 +74,7 @@ public DataFlavor[] getTransferDataFlavors() { * this object. * * @param flavor the requested flavor for the data - * @return boolean indicating wjether or not the data flavor is supported + * @return boolean indicating whether or not the data flavor is supported */ @Override public boolean isDataFlavorSupported(DataFlavor flavor) { diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/draw/CopyPasteBddTest.java b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/draw/CopyPasteBddTest.java new file mode 100644 index 000000000..35e763ee5 --- /dev/null +++ b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/draw/CopyPasteBddTest.java @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2026 JHotDraw. + */ +package org.jhotdraw.samples.draw; + +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import javax.swing.undo.UndoManager; +import org.jhotdraw.draw.DefaultDrawing; +import org.jhotdraw.draw.DefaultDrawingView; +import org.jhotdraw.draw.DefaultDrawingViewTransferHandler; +import org.jhotdraw.draw.figure.Figure; +import org.jhotdraw.draw.figure.RectangleFigure; +import org.jhotdraw.draw.figure.TextFigure; +import org.jhotdraw.draw.figure.TextHolderFigure; +import org.jhotdraw.draw.io.DOMStorableInputOutputFormat; +import org.jhotdraw.draw.io.TextInputFormat; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +public class CopyPasteBddTest { + + @Test + public void givenDrawingWithOneSelectedRectangle_whenUserCopiesAndPastesIt_thenDrawingContainsTwoRectanglesAndPastedRectangleIsSelected() { + ViewFixture fixture = ViewFixture.withDomFormat(); + RectangleFigure original = new RectangleFigure(10, 20, 30, 40); + fixture.drawing.add(original); + fixture.view.addToSelection(original); + + Transferable clipboardContent = fixture.handler.copyFrom(fixture.view); + boolean pasted = fixture.handler.importData(fixture.view, clipboardContent); + + assertTrue(pasted); + assertEquals(2, fixture.drawing.getChildCount()); + Figure pastedFigure = fixture.drawing.getChild(1); + assertTrue(pastedFigure instanceof RectangleFigure); + assertNotSame(original, pastedFigure); + assertEquals(1, fixture.view.getSelectionCount()); + assertTrue(fixture.view.isFigureSelected(pastedFigure)); + assertFalse(fixture.view.isFigureSelected(original)); + } + + @Test + public void givenDrawingViewWithNoSelectedFigures_whenUserInvokesCopy_thenNoDrawingFigureTransferableIsProduced() { + ViewFixture fixture = ViewFixture.withDomFormat(); + fixture.drawing.add(new RectangleFigure(10, 20, 30, 40)); + + Transferable clipboardContent = fixture.handler.copyFrom(fixture.view); + + assertNull(clipboardContent); + assertEquals(1, fixture.drawing.getChildCount()); + assertEquals(0, fixture.view.getSelectionCount()); + } + + @Test + public void givenClipboardContainsUnsupportedData_whenUserInvokesPaste_thenDrawingRemainsUnchanged() { + ViewFixture fixture = ViewFixture.withDomFormat(); + fixture.drawing.add(new RectangleFigure(10, 20, 30, 40)); + + boolean pasted = fixture.handler.importData(fixture.view, new StringSelection("plain text")); + + assertFalse(pasted); + assertEquals(1, fixture.drawing.getChildCount()); + assertEquals(0, fixture.view.getSelectionCount()); + } + + @Test + public void givenUserPastedFiguresIntoDrawing_whenUserInvokesUndoAndRedo_thenPastedFiguresAreRemovedAndAddedBack() { + ViewFixture fixture = ViewFixture.withDomFormat(); + UndoManager undoManager = new UndoManager(); + fixture.drawing.addUndoableEditListener(undoManager); + RectangleFigure original = new RectangleFigure(10, 20, 30, 40); + fixture.drawing.add(original); + fixture.view.addToSelection(original); + Transferable clipboardContent = fixture.handler.copyFrom(fixture.view); + + assertTrue(fixture.handler.importData(fixture.view, clipboardContent)); + assertEquals(2, fixture.drawing.getChildCount()); + + undoManager.undo(); + assertEquals(1, fixture.drawing.getChildCount()); + assertTrue(fixture.drawing.getChildren().contains(original)); + + undoManager.redo(); + assertEquals(2, fixture.drawing.getChildCount()); + } + + @Test + public void givenClipboardContainsPlainTextAndDrawingRegistersTextInputFormat_whenUserInvokesPaste_thenTextHolderFigureIsAdded() { + ViewFixture fixture = ViewFixture.withTextInputFormat(); + + boolean pasted = fixture.handler.importData(fixture.view, new StringSelection("hello")); + + assertTrue(pasted); + assertEquals(1, fixture.drawing.getChildCount()); + Figure pastedFigure = fixture.drawing.getChild(0); + assertTrue(pastedFigure instanceof TextHolderFigure); + assertEquals("hello", ((TextHolderFigure) pastedFigure).getText()); + assertEquals(1, fixture.view.getSelectionCount()); + assertTrue(fixture.view.isFigureSelected(pastedFigure)); + } + + private static class ViewFixture { + + private final BddTransferHandler handler = new BddTransferHandler(); + private final DefaultDrawing drawing = new DefaultDrawing(); + private final DefaultDrawingView view = new DefaultDrawingView(); + + static ViewFixture withDomFormat() { + ViewFixture fixture = new ViewFixture(); + DOMStorableInputOutputFormat format = + new DOMStorableInputOutputFormat(new DrawFigureFactory()); + fixture.drawing.addInputFormat(format); + fixture.drawing.addOutputFormat(format); + return fixture; + } + + static ViewFixture withTextInputFormat() { + ViewFixture fixture = new ViewFixture(); + fixture.drawing.addInputFormat(new TextInputFormat(new TextFigure())); + return fixture; + } + + private ViewFixture() { + view.setTransferHandler(handler); + view.setDrawing(drawing); + } + } + + private static class BddTransferHandler extends DefaultDrawingViewTransferHandler { + + private static final long serialVersionUID = 1L; + + Transferable copyFrom(DefaultDrawingView view) { + return super.createTransferable(view, view.getSelectedFigures()); + } + } +} diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/draw/DOMStorableInputOutputFormatTest.java b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/draw/DOMStorableInputOutputFormatTest.java new file mode 100644 index 000000000..b09118e48 --- /dev/null +++ b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/draw/DOMStorableInputOutputFormatTest.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2026 JHotDraw. + */ +package org.jhotdraw.samples.draw; + +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.geom.Rectangle2D; +import java.util.Collections; +import org.jhotdraw.draw.DefaultDrawing; +import org.jhotdraw.draw.figure.Figure; +import org.jhotdraw.draw.figure.RectangleFigure; +import org.jhotdraw.draw.io.DOMStorableInputOutputFormat; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertTrue; + +public class DOMStorableInputOutputFormatTest { + + private final DOMStorableInputOutputFormat format = + new DOMStorableInputOutputFormat(new DrawFigureFactory()); + + @Test + public void createsTransferableThatRoundTripsSelectedFigure() throws Exception { + RectangleFigure original = new RectangleFigure(10, 20, 30, 40); + DefaultDrawing source = new DefaultDrawing(); + source.add(original); + + Transferable transferable = + format.createTransferable(source, Collections.
singletonList(original), 1d); + + DefaultDrawing target = new DefaultDrawing(); + format.read(transferable, target, false); + + assertEquals(1, target.getChildCount()); + Figure pasted = target.getChild(0); + assertTrue(pasted instanceof RectangleFigure); + assertNotSame(original, pasted); + assertBoundsEqual(original.getBounds(), pasted.getBounds()); + } + + @Test + public void readWithReplaceClearsExistingFigures() throws Exception { + RectangleFigure copied = new RectangleFigure(1, 2, 3, 4); + RectangleFigure existing = new RectangleFigure(10, 20, 30, 40); + DefaultDrawing source = new DefaultDrawing(); + DefaultDrawing target = new DefaultDrawing(); + source.add(copied); + target.add(existing); + + Transferable transferable = + format.createTransferable(source, Collections.
singletonList(copied), 1d); + format.read(transferable, target, true); + + assertEquals(1, target.getChildCount()); + assertBoundsEqual(copied.getBounds(), target.getChild(0).getBounds()); + } + + @Test + public void rejectsUnsupportedDataFlavor() { + assertFalse(format.isDataFlavorSupported(DataFlavor.stringFlavor)); + } + + private static void assertBoundsEqual(Rectangle2D.Double expected, Rectangle2D.Double actual) { + assertEquals(expected.x, actual.x, 0.0001d); + assertEquals(expected.y, actual.y, 0.0001d); + assertEquals(expected.width, actual.width, 0.0001d); + assertEquals(expected.height, actual.height, 0.0001d); + } +} diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/draw/DefaultDrawingViewTransferHandlerTest.java b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/draw/DefaultDrawingViewTransferHandlerTest.java new file mode 100644 index 000000000..6ba2b2f74 --- /dev/null +++ b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/draw/DefaultDrawingViewTransferHandlerTest.java @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2026 JHotDraw. + */ +package org.jhotdraw.samples.draw; + +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.geom.Rectangle2D; +import java.util.Set; +import javax.swing.JComponent; +import javax.swing.undo.UndoManager; +import org.jhotdraw.draw.DefaultDrawing; +import org.jhotdraw.draw.DefaultDrawingView; +import org.jhotdraw.draw.DefaultDrawingViewTransferHandler; +import org.jhotdraw.draw.DrawingView; +import org.jhotdraw.draw.figure.Figure; +import org.jhotdraw.draw.figure.RectangleFigure; +import org.jhotdraw.draw.io.DOMStorableInputOutputFormat; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +public class DefaultDrawingViewTransferHandlerTest { + + @Test + public void copySelectedFigureCreatesTransferable() { + ViewFixture fixture = new ViewFixture(); + RectangleFigure original = new RectangleFigure(10, 20, 30, 40); + fixture.drawing.add(original); + fixture.view.addToSelection(original); + + Transferable transferable = fixture.handler.createTransferable( + fixture.view, + fixture.view.getSelectedFigures()); + + assertNotNull(transferable); + assertTrue(transferable.isDataFlavorSupported(fixture.format.getDataFlavor())); + } + + @Test + public void copyWithoutSelectionCreatesNoTransferable() { + ViewFixture fixture = new ViewFixture(); + fixture.drawing.add(new RectangleFigure(10, 20, 30, 40)); + + Transferable transferable = fixture.handler.createTransferable( + fixture.view, + fixture.view.getSelectedFigures()); + + assertEquals(1, fixture.drawing.getChildCount()); + assertFalse(fixture.view.getSelectionCount() > 0); + assertNull(transferable); + } + + @Test + public void pasteSupportedTransferableAddsAndSelectsImportedFigure() { + ViewFixture source = new ViewFixture(); + RectangleFigure original = new RectangleFigure(10, 20, 30, 40); + source.drawing.add(original); + source.view.addToSelection(original); + Transferable transferable = source.handler.createTransferable( + source.view, + source.view.getSelectedFigures()); + + ViewFixture target = new ViewFixture(); + boolean imported = target.handler.importData(target.view, transferable); + + assertTrue(imported); + assertEquals(1, target.drawing.getChildCount()); + Figure pasted = target.drawing.getChild(0); + assertTrue(pasted instanceof RectangleFigure); + assertNotSame(original, pasted); + assertBoundsEqual(original.getBounds(), pasted.getBounds()); + assertEquals(1, target.view.getSelectionCount()); + assertTrue(target.view.isFigureSelected(pasted)); + } + + @Test + public void pasteUnsupportedTransferableLeavesDrawingUnchanged() { + ViewFixture fixture = new ViewFixture(); + fixture.drawing.add(new RectangleFigure(10, 20, 30, 40)); + + boolean imported = fixture.handler.importData(fixture.view, new StringSelection("not a drawing")); + + assertFalse(imported); + assertEquals(1, fixture.drawing.getChildCount()); + assertEquals(0, fixture.view.getSelectionCount()); + } + + @Test + public void pasteFiresUndoableEditThatCanUndoAndRedoImportedFigure() { + ViewFixture source = new ViewFixture(); + RectangleFigure original = new RectangleFigure(10, 20, 30, 40); + source.drawing.add(original); + source.view.addToSelection(original); + Transferable transferable = source.handler.createTransferable( + source.view, + source.view.getSelectedFigures()); + + ViewFixture target = new ViewFixture(); + UndoManager undoManager = new UndoManager(); + target.drawing.addUndoableEditListener(undoManager); + + assertTrue(target.handler.importData(target.view, transferable)); + assertEquals(1, target.drawing.getChildCount()); + assertTrue(undoManager.canUndo()); + + undoManager.undo(); + assertEquals(0, target.drawing.getChildCount()); + + assertTrue(undoManager.canRedo()); + undoManager.redo(); + assertEquals(1, target.drawing.getChildCount()); + } + + private static void assertBoundsEqual(Rectangle2D.Double expected, Rectangle2D.Double actual) { + assertEquals(expected.x, actual.x, 0.0001d); + assertEquals(expected.y, actual.y, 0.0001d); + assertEquals(expected.width, actual.width, 0.0001d); + assertEquals(expected.height, actual.height, 0.0001d); + } + + private static class ViewFixture { + + private final ExposedTransferHandler handler = new ExposedTransferHandler(); + private final DOMFormatWithFlavor format = new DOMFormatWithFlavor(); + private final DefaultDrawing drawing = new DefaultDrawing(); + private final DefaultDrawingView view = new DefaultDrawingView(); + + ViewFixture() { + drawing.addInputFormat(format); + drawing.addOutputFormat(format); + view.setTransferHandler(handler); + view.setDrawing(drawing); + } + } + + private static class ExposedTransferHandler extends DefaultDrawingViewTransferHandler { + + private static final long serialVersionUID = 1L; + + public Transferable createTransferable(DrawingView view, Set
transferFigures) { + return super.createTransferable(view, transferFigures); + } + + @Override + public boolean importData(JComponent comp, Transferable t) { + return super.importData(comp, t); + } + } + + private static class DOMFormatWithFlavor extends DOMStorableInputOutputFormat { + + DOMFormatWithFlavor() { + super(new DrawFigureFactory()); + } + + DataFlavor getDataFlavor() { + Transferable transferable; + try { + DefaultDrawing drawing = new DefaultDrawing(); + RectangleFigure figure = new RectangleFigure(0, 0, 1, 1); + drawing.add(figure); + transferable = createTransferable(drawing, java.util.Collections.
singletonList(figure), 1d); + } catch (java.io.IOException ex) { + throw new AssertionError(ex); + } + return transferable.getTransferDataFlavors()[0]; + } + } +} diff --git a/pom.xml b/pom.xml index 5f6c7eef5..1a66ef2f7 100644 --- a/pom.xml +++ b/pom.xml @@ -8,13 +8,7 @@ JHotDraw - - - github - GitHub external Packages - https://maven.pkg.github.com/sweat-tek/MavenRepository - - + GNU Library or Lesser General Public License (LGPL) V2.1