diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
new file mode 100644
index 000000000..cf7930dd2
--- /dev/null
+++ b/.github/workflows/maven.yml
@@ -0,0 +1,33 @@
+# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
+# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven
+
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+
+name: Java CI with Maven
+
+on:
+ push:
+ branches: ["develop"]
+ pull_request:
+ branches: ["develop"]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v3
+ - name: Set up JDK 11
+ uses: actions/setup-java@v3
+ with:
+ java-version: "11"
+ distribution: "temurin"
+ cache: maven
+ - name: Build with Maven
+ run: mvn -s settings.xml -B package --file pom.xml
+ env:
+ USER_NAME: ${{ secrets.USER_NAME }}
+ ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 24f860174..3e751f712 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,4 @@ nb-configuration.xml
.idea/*
*.ftf
/jhotdraw-samples/jhotdraw-samples-misc/nbproject/
+jhotdraw-samples/jhotdraw-samples-misc/pom.xml
diff --git a/jhotdraw-actions/jhotdraw-actions.iml b/jhotdraw-actions/jhotdraw-actions.iml
new file mode 100644
index 000000000..eba793956
--- /dev/null
+++ b/jhotdraw-actions/jhotdraw-actions.iml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jhotdraw-actions/pom.xml b/jhotdraw-actions/pom.xml
index 5cc33e1c6..3a5747bf1 100644
--- a/jhotdraw-actions/pom.xml
+++ b/jhotdraw-actions/pom.xml
@@ -24,5 +24,11 @@
jhotdraw-datatransfer
${project.version}
+
+ dk.sdu.cbse
+ featuretracerlite
+ 1.1-SNAPSHOT
+ compile
+
\ No newline at end of file
diff --git a/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/CopyAction.java b/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/CopyAction.java
index 208e82405..e49d67773 100644
--- a/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/CopyAction.java
+++ b/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/CopyAction.java
@@ -10,6 +10,8 @@
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
+
+import dk.sdu.mmmi.featuretracer.lib.FeatureEntryPoint;
import org.jhotdraw.datatransfer.ClipboardUtil;
import org.jhotdraw.util.*;
@@ -48,6 +50,7 @@ public CopyAction() {
* @param target The target of the action. Specify null for the currently
* focused component.
*/
+@FeatureEntryPoint(value="CopyAction")
public CopyAction(JComponent target) {
super(target);
ResourceBundleUtil labels = ResourceBundleUtil.getBundle("org.jhotdraw.action.Labels");
diff --git a/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/CutAction.java b/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/CutAction.java
index 044bb4aa7..3396158b1 100644
--- a/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/CutAction.java
+++ b/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/CutAction.java
@@ -10,6 +10,8 @@
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
+
+import dk.sdu.mmmi.featuretracer.lib.FeatureEntryPoint;
import org.jhotdraw.datatransfer.ClipboardUtil;
import org.jhotdraw.util.*;
@@ -48,6 +50,7 @@ public CutAction() {
* @param target The target of the action. Specify null for the currently
* focused component.
*/
+ @FeatureEntryPoint(value="CutAction")
public CutAction(JComponent target) {
super(target);
ResourceBundleUtil labels = ResourceBundleUtil.getBundle("org.jhotdraw.action.Labels");
diff --git a/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/DeleteAction.java b/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/DeleteAction.java
index 05ae13f58..ef7df88f8 100644
--- a/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/DeleteAction.java
+++ b/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/DeleteAction.java
@@ -13,6 +13,8 @@
import java.beans.PropertyChangeListener;
import javax.swing.JComponent;
import javax.swing.text.*;
+
+import dk.sdu.mmmi.featuretracer.lib.FeatureEntryPoint;
import org.jhotdraw.api.gui.EditableComponent;
import org.jhotdraw.beans.WeakPropertyChangeListener;
import org.jhotdraw.util.*;
@@ -89,6 +91,7 @@ public DeleteAction(JComponent target) {
* @param target The target of the action. Specify null for the currently
* focused component.
*/
+ @FeatureEntryPoint(value="DeleteAction")
protected DeleteAction(JComponent target, String id) {
super(id);
this.target = target;
diff --git a/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/DuplicateAction.java b/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/DuplicateAction.java
index 5c7fa23ab..f368b6a3b 100644
--- a/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/DuplicateAction.java
+++ b/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/DuplicateAction.java
@@ -10,6 +10,8 @@
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
+
+import dk.sdu.mmmi.featuretracer.lib.FeatureEntryPoint;
import org.jhotdraw.api.gui.EditableComponent;
import org.jhotdraw.util.*;
@@ -63,6 +65,7 @@ public DuplicateAction() {
* @param target The target of the action. Specify null for the currently
* focused component.
*/
+ @FeatureEntryPoint(value="DuplicateAction")
public DuplicateAction(JComponent target) {
super(target);
ResourceBundleUtil labels = ResourceBundleUtil.getBundle("org.jhotdraw.action.Labels");
diff --git a/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/PasteAction.java b/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/PasteAction.java
index 44f3a0953..ea04044ed 100644
--- a/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/PasteAction.java
+++ b/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/PasteAction.java
@@ -11,6 +11,8 @@
import java.awt.datatransfer.*;
import java.awt.event.*;
import javax.swing.*;
+
+import dk.sdu.mmmi.featuretracer.lib.FeatureEntryPoint;
import org.jhotdraw.datatransfer.ClipboardUtil;
import org.jhotdraw.util.*;
@@ -49,6 +51,8 @@ public PasteAction() {
* @param target The target of the action. Specify null for the currently
* focused component.
*/
+ @FeatureEntryPoint(value="PasteAction")
+
public PasteAction(JComponent target) {
super(target);
ResourceBundleUtil labels = ResourceBundleUtil.getBundle("org.jhotdraw.action.Labels");
diff --git a/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/RedoAction.java b/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/RedoAction.java
index 794ab08c8..d8489542a 100644
--- a/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/RedoAction.java
+++ b/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/RedoAction.java
@@ -10,6 +10,8 @@
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;
+
+import dk.sdu.mmmi.featuretracer.lib.FeatureEntryPoint;
import org.jhotdraw.action.AbstractViewAction;
import org.jhotdraw.api.app.Application;
import org.jhotdraw.api.app.View;
@@ -52,6 +54,8 @@ public void propertyChange(PropertyChangeEvent evt) {
/**
* Creates a new instance.
*/
+
+ @FeatureEntryPoint("RedoAction")
public RedoAction(Application app, View view) {
super(app, view);
labels.configureAction(this, ID);
diff --git a/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/UndoAction.java b/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/UndoAction.java
index 74c4f2cea..a8e8d2713 100644
--- a/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/UndoAction.java
+++ b/jhotdraw-actions/src/main/java/org/jhotdraw/action/edit/UndoAction.java
@@ -10,6 +10,8 @@
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;
+
+import dk.sdu.mmmi.featuretracer.lib.FeatureEntryPoint;
import org.jhotdraw.action.AbstractViewAction;
import org.jhotdraw.api.app.Application;
import org.jhotdraw.api.app.View;
@@ -51,6 +53,8 @@ public void propertyChange(PropertyChangeEvent evt) {
/**
* Creates a new instance.
*/
+
+ @FeatureEntryPoint("UndoAction")
public UndoAction(Application app, View view) {
super(app, view);
labels.configureAction(this, ID);
diff --git a/jhotdraw-api/jhotdraw-api.iml b/jhotdraw-api/jhotdraw-api.iml
new file mode 100644
index 000000000..7bd80fa97
--- /dev/null
+++ b/jhotdraw-api/jhotdraw-api.iml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jhotdraw-app/jhotdraw-app.iml b/jhotdraw-app/jhotdraw-app.iml
new file mode 100644
index 000000000..1d28c78f5
--- /dev/null
+++ b/jhotdraw-app/jhotdraw-app.iml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jhotdraw-core/jhotdraw-core.iml b/jhotdraw-core/jhotdraw-core.iml
new file mode 100644
index 000000000..86849407b
--- /dev/null
+++ b/jhotdraw-core/jhotdraw-core.iml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jhotdraw-core/src/main/java/org/jhotdraw/draw/io/TextInputFormat.java b/jhotdraw-core/src/main/java/org/jhotdraw/draw/io/TextInputFormat.java
index ea6eac74e..9496dd36d 100644
--- a/jhotdraw-core/src/main/java/org/jhotdraw/draw/io/TextInputFormat.java
+++ b/jhotdraw-core/src/main/java/org/jhotdraw/draw/io/TextInputFormat.java
@@ -57,10 +57,6 @@ public class TextInputFormat implements InputFormat {
* File name extension used for the file filter.
*/
private String fileExtension;
- /**
- * Image IO image format name.
- */
- private String formatName;
/**
* This should be set to true for ImageHolderFigures that can hold multiple
* lines of text.
@@ -89,7 +85,9 @@ public TextInputFormat(TextHolderFigure prototype) {
public TextInputFormat(TextHolderFigure prototype, String formatName,
String description, String fileExtension, boolean isMultiline) {
this.prototype = prototype;
- this.formatName = formatName;
+ /**
+ * Image IO image format name.
+ */
this.description = description;
this.fileExtension = fileExtension;
this.isMultiline = isMultiline;
@@ -137,7 +135,7 @@ public void read(InputStream in, Drawing drawing, boolean replace) throws IOExce
drawing.basicAddAll(0, createTextHolderFigures(in));
}
- public LinkedList createTextHolderFigures(InputStream in) throws IOException {
+ public List createTextHolderFigures(InputStream in) throws IOException {
LinkedList list = new LinkedList<>();
BufferedReader r = new BufferedReader(new InputStreamReader(in, "UTF8"));
if (isMultiline) {
@@ -169,7 +167,7 @@ public LinkedList createTextHolderFigures(InputStream in) throws IOExcep
y += s.height;
}
}
- if (list.size() == 0) {
+ if (list.isEmpty()) {
throw new IOException("No text found");
}
return list;
diff --git a/jhotdraw-datatransfer/jhotdraw-datatransfer.iml b/jhotdraw-datatransfer/jhotdraw-datatransfer.iml
new file mode 100644
index 000000000..a05f213c9
--- /dev/null
+++ b/jhotdraw-datatransfer/jhotdraw-datatransfer.iml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jhotdraw-gui/jhotdraw-gui.iml b/jhotdraw-gui/jhotdraw-gui.iml
new file mode 100644
index 000000000..875f470e9
--- /dev/null
+++ b/jhotdraw-gui/jhotdraw-gui.iml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jhotdraw-samples/jhotdraw-samples-mini/jhotdraw-samples-mini.iml b/jhotdraw-samples/jhotdraw-samples-mini/jhotdraw-samples-mini.iml
new file mode 100644
index 000000000..5fbc2ca35
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-mini/jhotdraw-samples-mini.iml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/jgiven-reports/org.jhotdraw.samples.svg.DeleteDrawingBDDTest.json b/jhotdraw-samples/jhotdraw-samples-misc/jgiven-reports/org.jhotdraw.samples.svg.DeleteDrawingBDDTest.json
new file mode 100644
index 000000000..9cff954cb
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/jgiven-reports/org.jhotdraw.samples.svg.DeleteDrawingBDDTest.json
@@ -0,0 +1,71 @@
+{
+ "className": "org.jhotdraw.samples.svg.DeleteDrawingBDDTest",
+ "name": "Delete Drawing BDD",
+ "scenarios": [
+ {
+ "className": "org.jhotdraw.samples.svg.DeleteDrawingBDDTest",
+ "testMethodName": "deleteDrawing",
+ "description": "Delete drawing",
+ "tagIds": [],
+ "explicitParameters": [],
+ "derivedParameters": [],
+ "casesAsTable": false,
+ "scenarioCases": [
+ {
+ "caseNr": 1,
+ "steps": [
+ {
+ "name": "empty drawing",
+ "words": [
+ {
+ "value": "Given",
+ "isIntroWord": true
+ },
+ {
+ "value": "empty drawing"
+ }
+ ],
+ "status": "PASSED",
+ "durationInNanos": 135710200
+ },
+ {
+ "name": "deleting the drawing",
+ "words": [
+ {
+ "value": "When",
+ "isIntroWord": true
+ },
+ {
+ "value": "deleting the drawing"
+ }
+ ],
+ "status": "PASSED",
+ "durationInNanos": 446600
+ },
+ {
+ "name": "the drawing is deleted",
+ "words": [
+ {
+ "value": "Then",
+ "isIntroWord": true
+ },
+ {
+ "value": "the drawing is deleted"
+ }
+ ],
+ "status": "PASSED",
+ "durationInNanos": 366700
+ }
+ ],
+ "explicitArguments": [],
+ "derivedArguments": [],
+ "status": "SUCCESS",
+ "durationInNanos": 170965400
+ }
+ ],
+ "durationInNanos": 170965400,
+ "executionStatus": "SUCCESS"
+ }
+ ],
+ "tagMap": {}
+}
\ No newline at end of file
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/jgiven-reports/org.jhotdraw.samples.svg.ImageFeatureBehaviourTest.json b/jhotdraw-samples/jhotdraw-samples-misc/jgiven-reports/org.jhotdraw.samples.svg.ImageFeatureBehaviourTest.json
new file mode 100644
index 000000000..cf7acede4
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/jgiven-reports/org.jhotdraw.samples.svg.ImageFeatureBehaviourTest.json
@@ -0,0 +1,71 @@
+{
+ "className": "org.jhotdraw.samples.svg.ImageFeatureBehaviourTest",
+ "name": "Image Feature Behaviour",
+ "scenarios": [
+ {
+ "className": "org.jhotdraw.samples.svg.ImageFeatureBehaviourTest",
+ "testMethodName": "drawImage",
+ "description": "Draw image",
+ "tagIds": [],
+ "explicitParameters": [],
+ "derivedParameters": [],
+ "casesAsTable": false,
+ "scenarioCases": [
+ {
+ "caseNr": 1,
+ "steps": [
+ {
+ "name": "an empty drawing",
+ "words": [
+ {
+ "value": "Given",
+ "isIntroWord": true
+ },
+ {
+ "value": "an empty drawing"
+ }
+ ],
+ "status": "PASSED",
+ "durationInNanos": 142936200
+ },
+ {
+ "name": "an image is drawn",
+ "words": [
+ {
+ "value": "When",
+ "isIntroWord": true
+ },
+ {
+ "value": "an image is drawn"
+ }
+ ],
+ "status": "PASSED",
+ "durationInNanos": 22861600
+ },
+ {
+ "name": "the drawing cointans the drawn image",
+ "words": [
+ {
+ "value": "Then",
+ "isIntroWord": true
+ },
+ {
+ "value": "the drawing cointans the drawn image"
+ }
+ ],
+ "status": "PASSED",
+ "durationInNanos": 2560300
+ }
+ ],
+ "explicitArguments": [],
+ "derivedArguments": [],
+ "status": "SUCCESS",
+ "durationInNanos": 192670400
+ }
+ ],
+ "durationInNanos": 192670400,
+ "executionStatus": "SUCCESS"
+ }
+ ],
+ "tagMap": {}
+}
\ No newline at end of file
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/jgiven-reports/org.jhotdraw.samples.svg.figures.SVGRectFigureBDDTest.json b/jhotdraw-samples/jhotdraw-samples-misc/jgiven-reports/org.jhotdraw.samples.svg.figures.SVGRectFigureBDDTest.json
new file mode 100644
index 000000000..5f2566a74
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/jgiven-reports/org.jhotdraw.samples.svg.figures.SVGRectFigureBDDTest.json
@@ -0,0 +1,76 @@
+{
+ "className": "org.jhotdraw.samples.svg.figures.SVGRectFigureBDDTest",
+ "name": "SVG Rect Figure BDD",
+ "scenarios": [
+ {
+ "className": "org.jhotdraw.samples.svg.figures.SVGRectFigureBDDTest",
+ "testMethodName": "drawRectangle",
+ "description": "Draw rectangle",
+ "tagIds": [],
+ "explicitParameters": [],
+ "derivedParameters": [],
+ "scenarioCases": [
+ {
+ "caseNr": 1,
+ "steps": [
+ {
+ "name": "empty canvas",
+ "words": [
+ {
+ "value": "Given",
+ "isIntroWord": true
+ },
+ {
+ "value": "empty canvas"
+ }
+ ],
+ "status": "PASSED",
+ "durationInNanos": 232622500,
+ "depth": 0,
+ "parentFailed": false
+ },
+ {
+ "name": "a rectangle is drawn",
+ "words": [
+ {
+ "value": "When",
+ "isIntroWord": true
+ },
+ {
+ "value": "a rectangle is drawn"
+ }
+ ],
+ "status": "PASSED",
+ "durationInNanos": 45962300,
+ "depth": 0,
+ "parentFailed": false
+ },
+ {
+ "name": "canvas contains rectangle",
+ "words": [
+ {
+ "value": "Then",
+ "isIntroWord": true
+ },
+ {
+ "value": "canvas contains rectangle"
+ }
+ ],
+ "status": "PASSED",
+ "durationInNanos": 16249500,
+ "depth": 0,
+ "parentFailed": false
+ }
+ ],
+ "explicitArguments": [],
+ "derivedArguments": [],
+ "status": "SUCCESS",
+ "durationInNanos": 334821600
+ }
+ ],
+ "casesAsTable": false,
+ "durationInNanos": 334821600
+ }
+ ],
+ "tagMap": {}
+}
\ No newline at end of file
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/jhotdraw-samples-misc.iml b/jhotdraw-samples/jhotdraw-samples-misc/jhotdraw-samples-misc.iml
new file mode 100644
index 000000000..8b25c3a52
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/jhotdraw-samples-misc.iml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/pom.xml b/jhotdraw-samples/jhotdraw-samples-misc/pom.xml
index 1d63de64d..b120f1536 100644
--- a/jhotdraw-samples/jhotdraw-samples-misc/pom.xml
+++ b/jhotdraw-samples/jhotdraw-samples-misc/pom.xml
@@ -1,5 +1,6 @@
-
+
4.0.0
org.jhotdraw
@@ -8,7 +9,24 @@
jhotdraw-samples-misc
jar
+
+
+ github
+ GitHub external Packages
+ https://maven.pkg.github.com/sweat-tek/MavenRepository
+
+
+
+ dk.sdu.cbse
+ featuretracerlite
+ 1.1-SNAPSHOT
+
+
+ org.aspectj
+ aspectjweaver
+ 1.9.9
+
${project.groupId}
jhotdraw-core
@@ -24,11 +42,6 @@
htmlunit
2.37.0
-
- org.aspectj
- aspectjweaver
- 1.9.9
-
${project.groupId}
jhotdraw-app
@@ -40,26 +53,74 @@
4.13.2
test
+
+ org.mockito
+ mockito-core
+ 3.11.2
+ test
+
+
+ dk.sdu.cbse
+ featuretracerlite
+ 1.1-SNAPSHOT
+
+
+ com.tngtech.jgiven
+ jgiven-junit
+ 1.0.0-RC6
+ test
+
+
+ org.slf4j
+ slf4j-api
+ 2.0.9
+ compile
+
+
+
+ org.slf4j
+ slf4j-simple
+ 2.0.10
+ test
+
-
- org.codehaus.mojo
- exec-maven-plugin
- 3.1.0
-
-
- run-java
- install
-
- java
-
-
-
-
- org.jhotdraw.samples.svg.Main
-
-
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.22.2
+
+
+ true
+ always
+ true
+
+
\ No newline at end of file
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/net/NetPanel.java b/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/net/NetPanel.java
index 64d9a2e42..838cd58e4 100644
--- a/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/net/NetPanel.java
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/net/NetPanel.java
@@ -10,11 +10,8 @@
import java.awt.*;
import java.util.*;
import javax.swing.*;
-import org.jhotdraw.action.edit.CopyAction;
-import org.jhotdraw.action.edit.CutAction;
-import org.jhotdraw.action.edit.DuplicateAction;
-import org.jhotdraw.action.edit.PasteAction;
-import org.jhotdraw.action.edit.SelectAllAction;
+
+import org.jhotdraw.action.edit.*;
import org.jhotdraw.draw.AttributeKey;
import org.jhotdraw.draw.AttributeKeys;
import org.jhotdraw.draw.DefaultDrawing;
@@ -67,6 +64,7 @@ public NetPanel() {
pb.add(new BringToFrontAction(editor));
pb.add(new SendToBackAction(editor));
pb.addSeparator();
+ pb.add(new DeleteAction());
pb.add(new CutAction());
pb.add(new CopyAction());
pb.add(new PasteAction());
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/Main.java b/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/Main.java
index 11e156729..a690f09cd 100644
--- a/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/Main.java
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/Main.java
@@ -26,6 +26,8 @@ public class Main {
/**
* Creates a new instance.
*/
+
+ //@FeatureEntryPoint("Main")
public static void main(String[] args) {
// Debug resource bundle
ResourceBundleUtil.setVerbose(true);
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/figures/HandleHelper.java b/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/figures/HandleHelper.java
new file mode 100644
index 000000000..37dfa78b6
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/figures/HandleHelper.java
@@ -0,0 +1,31 @@
+package org.jhotdraw.samples.svg.figures;
+
+import org.jhotdraw.draw.figure.Figure;
+import org.jhotdraw.draw.handle.BoundsOutlineHandle;
+import org.jhotdraw.draw.handle.Handle;
+import org.jhotdraw.draw.handle.ResizeHandleKit;
+import org.jhotdraw.draw.handle.TransformHandleKit;
+
+import java.util.Collection;
+import java.util.LinkedList;
+
+public class HandleHelper {
+ public static Collection createHandles(int detailLevel, Figure figure) {
+ LinkedList handles = new LinkedList<>();
+ switch (detailLevel % 2) {
+ case -1: // Mouse hover handles
+ handles.add(new BoundsOutlineHandle(figure, false, true));
+ break;
+ case 0:
+ ResizeHandleKit.addResizeHandles(figure, handles);
+ handles.add(new LinkHandle(figure));
+ break;
+ case 1:
+ TransformHandleKit.addTransformHandles(figure, handles);
+ break;
+ default:
+ break;
+ }
+ return handles;
+ }
+}
\ No newline at end of file
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/figures/SVGEllipseFigure.java b/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/figures/SVGEllipseFigure.java
index af2de2f19..95aa78b62 100644
--- a/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/figures/SVGEllipseFigure.java
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/figures/SVGEllipseFigure.java
@@ -7,21 +7,25 @@
*/
package org.jhotdraw.samples.svg.figures;
-import java.awt.*;
-import java.awt.geom.*;
-import java.util.*;
-import org.jhotdraw.draw.*;
-import static org.jhotdraw.draw.AttributeKeys.FILL_COLOR;
-import static org.jhotdraw.draw.AttributeKeys.TRANSFORM;
-import org.jhotdraw.draw.handle.BoundsOutlineHandle;
+import dk.sdu.mmmi.featuretracer.lib.FeatureEntryPoint;
+import org.jhotdraw.draw.AttributeKeys;
import org.jhotdraw.draw.handle.Handle;
-import org.jhotdraw.draw.handle.ResizeHandleKit;
-import org.jhotdraw.draw.handle.TransformHandleKit;
import org.jhotdraw.geom.Geom;
import org.jhotdraw.geom.GrowStroke;
import org.jhotdraw.samples.svg.Gradient;
import org.jhotdraw.samples.svg.SVGAttributeKeys;
-import static org.jhotdraw.samples.svg.SVGAttributeKeys.*;
+
+import java.awt.*;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.Collection;
+
+import static org.jhotdraw.draw.AttributeKeys.FILL_COLOR;
+import static org.jhotdraw.draw.AttributeKeys.TRANSFORM;
+import static org.jhotdraw.samples.svg.SVGAttributeKeys.FILL_GRADIENT;
+import static org.jhotdraw.samples.svg.SVGAttributeKeys.STROKE_GRADIENT;
/**
* SVGEllipse represents a SVG ellipse and a SVG circle element.
@@ -29,7 +33,7 @@
* @author Werner Randelshofer
* @version $Id$
*/
-public class SVGEllipseFigure extends SVGAttributedFigure implements SVGFigure {
+public class SVGEllipseFigure extends SVGAttributedFigure implements SVGFigure{
private static final long serialVersionUID = 1L;
private Ellipse2D.Double ellipse;
@@ -49,6 +53,7 @@ public SVGEllipseFigure() {
this(0, 0, 0, 0);
}
+ @FeatureEntryPoint("SVGEllipseTool")
public SVGEllipseFigure(double x, double y, double width, double height) {
ellipse = new Ellipse2D.Double(x, y, width, height);
SVGAttributeKeys.setDefaults(this);
@@ -96,6 +101,8 @@ public Rectangle2D.Double getBounds() {
public Rectangle2D.Double getDrawingArea() {
Rectangle2D rx = getTransformedShape().getBounds2D();
Rectangle2D.Double r = (rx instanceof Rectangle2D.Double) ? (Rectangle2D.Double) rx : new Rectangle2D.Double(rx.getX(), rx.getY(), rx.getWidth(), rx.getHeight());
+ // Assertion: The drawing area must not be null
+ assert r != null : "Drawing area is null";
if (get(TRANSFORM) == null) {
double g = SVGAttributeKeys.getPerpendicularHitGrowth(this, 1.0) * 2d + 1;
Geom.grow(r, g, g);
@@ -116,30 +123,42 @@ public boolean contains(Point2D.Double p) {
return getHitShape().contains(p);
}
+ /*
+ * This method is used to determine the transformed shape of the figure.
+ */
private Shape getTransformedShape() {
- if (cachedTransformedShape == null) {
- if (get(TRANSFORM) == null) {
- cachedTransformedShape = ellipse;
- } else {
- cachedTransformedShape = get(TRANSFORM).createTransformedShape(ellipse);
- }
+ if (cachedTransformedShape != null) {
+ return cachedTransformedShape;
+ }
+ if (get(TRANSFORM) == null) {
+ cachedTransformedShape = ellipse;
+ } else {
+ cachedTransformedShape = get(TRANSFORM).createTransformedShape(ellipse);
}
return cachedTransformedShape;
}
+ /*
+ * This method is used to determine the hit shape of the figure.
+ */
private Shape getHitShape() {
- if (cachedHitShape == null) {
- if (get(FILL_COLOR) != null || get(FILL_GRADIENT) != null) {
- cachedHitShape = new GrowStroke(
- (float) SVGAttributeKeys.getStrokeTotalWidth(this, 1.0) / 2f,
- (float) SVGAttributeKeys.getStrokeTotalMiterLimit(this, 1.0)).createStrokedShape(getTransformedShape());
- } else {
- cachedHitShape = SVGAttributeKeys.getHitStroke(this, 1.0).createStrokedShape(getTransformedShape());
- }
+ if (cachedHitShape != null) {
+ return cachedHitShape;
+ }
+ if (get(FILL_COLOR) != null || get(FILL_GRADIENT) != null) {
+ cachedHitShape = new GrowStroke(
+ (float) AttributeKeys.getStrokeTotalWidth(this, 1.0) / 2f,
+ (float) AttributeKeys.getStrokeTotalMiterLimit(this, 1.0)).createStrokedShape(getTransformedShape());
+ } else {
+ cachedHitShape = AttributeKeys.getHitStroke(this, 1.0).createStrokedShape(getTransformedShape());
}
return cachedHitShape;
}
+ /*
+ * This method is used to determine the drawing area of the figure.
+ */
+
@Override
public void setBounds(Point2D.Double anchor, Point2D.Double lead) {
ellipse.x = Math.min(anchor.x, lead.x);
@@ -187,6 +206,9 @@ public void transform(AffineTransform tx) {
invalidate();
}
+ /*
+ * This method is used to restore the transform of the figure.
+ */
@Override
public void restoreTransformTo(Object geometry) {
Object[] restoreData = (Object[]) geometry;
@@ -197,40 +219,31 @@ public void restoreTransformTo(Object geometry) {
invalidate();
}
+ /*
+ * This method is used to get the transform restore data of the figure.
+ */
@Override
public Object getTransformRestoreData() {
return new Object[]{
- ellipse.clone(),
- TRANSFORM.getClone(this),
- FILL_GRADIENT.getClone(this),
- STROKE_GRADIENT.getClone(this)};
+ ellipse.clone(),
+ TRANSFORM.getClone(this),
+ FILL_GRADIENT.getClone(this),
+ STROKE_GRADIENT.getClone(this)};
}
// ATTRIBUTES
// EDITING
@Override
public Collection createHandles(int detailLevel) {
- LinkedList handles = new LinkedList();
- switch (detailLevel % 2) {
- case -1: // Mouse hover handles
- handles.add(new BoundsOutlineHandle(this, false, true));
- break;
- case 0:
- ResizeHandleKit.addResizeHandles(this, handles);
- handles.add(new LinkHandle(this));
- break;
- case 1:
- TransformHandleKit.addTransformHandles(this, handles);
- break;
- default:
- break;
- }
- return handles;
+ return HandleHelper.createHandles(detailLevel, this);
}
// CONNECTING
// COMPOSITE FIGURES
// CLONING
+ /*
+ * This method is used to clone the figure.
+ */
@Override
public SVGEllipseFigure clone() {
SVGEllipseFigure that = (SVGEllipseFigure) super.clone();
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/figures/SVGImageFigure.java b/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/figures/SVGImageFigure.java
index bb6152c85..b15119e08 100644
--- a/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/figures/SVGImageFigure.java
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/figures/SVGImageFigure.java
@@ -7,25 +7,29 @@
*/
package org.jhotdraw.samples.svg.figures;
+import dk.sdu.mmmi.featuretracer.lib.FeatureEntryPoint;
+import org.jhotdraw.draw.AttributeKeys;
import org.jhotdraw.draw.figure.ImageHolderFigure;
+
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.io.*;
+import java.nio.file.Files;
import java.util.*;
import javax.imageio.ImageIO;
import javax.swing.*;
-import org.jhotdraw.draw.*;
+
import static org.jhotdraw.draw.AttributeKeys.TRANSFORM;
+
import org.jhotdraw.draw.event.TransformRestoreEdit;
-import org.jhotdraw.draw.handle.BoundsOutlineHandle;
import org.jhotdraw.draw.handle.Handle;
-import org.jhotdraw.draw.handle.ResizeHandleKit;
-import org.jhotdraw.draw.handle.TransformHandleKit;
import org.jhotdraw.geom.GrowStroke;
import org.jhotdraw.samples.svg.SVGAttributeKeys;
+
import static org.jhotdraw.samples.svg.SVGAttributeKeys.*;
+
import org.jhotdraw.util.*;
/**
@@ -67,6 +71,7 @@ public SVGImageFigure() {
this(0, 0, 0, 0);
}
+ @FeatureEntryPoint("Image")
public SVGImageFigure(double x, double y, double width, double height) {
rectangle = new Rectangle2D.Double(x, y, width, height);
SVGAttributeKeys.setDefaults(this);
@@ -76,7 +81,6 @@ public SVGImageFigure(double x, double y, double width, double height) {
// DRAWING
@Override
public void draw(Graphics2D g) {
- //super.draw(g);
double opacity = get(OPACITY);
opacity = Math.min(Math.max(0d, opacity), 1d);
if (opacity != 0d) {
@@ -143,8 +147,7 @@ public Rectangle2D.Double getBounds() {
@Override
public Rectangle2D.Double getDrawingArea() {
Rectangle2D rx = getTransformedShape().getBounds2D();
- Rectangle2D.Double r = (rx instanceof Rectangle2D.Double) ? (Rectangle2D.Double) rx : new Rectangle2D.Double(rx.getX(), rx.getY(), rx.getWidth(), rx.getHeight());
- return r;
+ return (rx instanceof Rectangle2D.Double) ? (Rectangle2D.Double) rx : new Rectangle2D.Double(rx.getX(), rx.getY(), rx.getWidth(), rx.getHeight());
}
/**
@@ -182,8 +185,8 @@ private Shape getTransformedShape() {
private Shape getHitShape() {
if (cachedHitShape == null) {
cachedHitShape = new GrowStroke(
- (float) SVGAttributeKeys.getStrokeTotalWidth(this, 1.0) / 2f,
- (float) SVGAttributeKeys.getStrokeTotalMiterLimit(this, 1.0)).createStrokedShape(getTransformedShape());
+ (float) AttributeKeys.getStrokeTotalWidth(this, 1.0) / 2f,
+ (float) AttributeKeys.getStrokeTotalMiterLimit(this, 1.0)).createStrokedShape(getTransformedShape());
}
return cachedHitShape;
}
@@ -230,36 +233,21 @@ public void restoreTransformTo(Object geometry) {
@Override
public Object getTransformRestoreData() {
return new Object[]{
- rectangle.clone(),
- get(TRANSFORM)
+ rectangle.clone(),
+ get(TRANSFORM)
};
}
// EDITING
@Override
public Collection createHandles(int detailLevel) {
- LinkedList handles = new LinkedList();
- switch (detailLevel % 2) {
- case -1: // Mouse hover handles
- handles.add(new BoundsOutlineHandle(this, false, true));
- break;
- case 0:
- ResizeHandleKit.addResizeHandles(this, handles);
- handles.add(new LinkHandle(this));
- break;
- case 1:
- TransformHandleKit.addTransformHandles(this, handles);
- break;
- default:
- break;
- }
- return handles;
+ return HandleHelper.createHandles(detailLevel, this);
}
@Override
public Collection getActions(Point2D.Double p) {
final ResourceBundleUtil labels = ResourceBundleUtil.getBundle("org.jhotdraw.samples.svg.Labels");
- LinkedList actions = new LinkedList();
+ LinkedList actions = new LinkedList<>();
if (get(TRANSFORM) != null) {
actions.add(new AbstractAction(labels.getString("edit.removeTransform.text")) {
private static final long serialVersionUID = 1L;
@@ -273,6 +261,7 @@ public void actionPerformed(ActionEvent evt) {
}
});
}
+
if (bufferedImage != null) {
if (rectangle.width != bufferedImage.getWidth()
|| rectangle.height != bufferedImage.getHeight()) {
@@ -281,16 +270,7 @@ public void actionPerformed(ActionEvent evt) {
@Override
public void actionPerformed(ActionEvent evt) {
- Object geometry = getTransformRestoreData();
- willChange();
- rectangle = new Rectangle2D.Double(
- rectangle.x - (bufferedImage.getWidth() - rectangle.width) / 2d,
- rectangle.y - (bufferedImage.getHeight() - rectangle.height) / 2d,
- bufferedImage.getWidth(),
- bufferedImage.getHeight());
- fireUndoableEditHappened(
- new TransformRestoreEdit(SVGImageFigure.this, geometry, getTransformRestoreData()));
- changed();
+ actionsPerformed1();
}
});
}
@@ -302,13 +282,7 @@ public void actionPerformed(ActionEvent evt) {
@Override
public void actionPerformed(ActionEvent evt) {
- Object geometry = getTransformRestoreData();
- willChange();
- double newHeight = bufferedImage.getHeight() * rectangle.width / bufferedImage.getWidth();
- rectangle = new Rectangle2D.Double(rectangle.x, rectangle.y - (newHeight - rectangle.height) / 2d, rectangle.width, newHeight);
- fireUndoableEditHappened(
- new TransformRestoreEdit(SVGImageFigure.this, geometry, getTransformRestoreData()));
- changed();
+ actionsPerformed2();
}
});
actions.add(new AbstractAction(labels.getString("edit.adjustWidthToImageAspect.text")) {
@@ -316,13 +290,7 @@ public void actionPerformed(ActionEvent evt) {
@Override
public void actionPerformed(ActionEvent evt) {
- Object geometry = getTransformRestoreData();
- willChange();
- double newWidth = bufferedImage.getWidth() * rectangle.height / bufferedImage.getHeight();
- rectangle = new Rectangle2D.Double(rectangle.x - (newWidth - rectangle.width) / 2d, rectangle.y, newWidth, rectangle.height);
- fireUndoableEditHappened(
- new TransformRestoreEdit(SVGImageFigure.this, geometry, getTransformRestoreData()));
- changed();
+ actionsPerformed3();
}
});
}
@@ -330,16 +298,50 @@ public void actionPerformed(ActionEvent evt) {
return actions;
}
+ private void actionsPerformed1(){
+ Object geometry = getTransformRestoreData();
+ willChange();
+ rectangle = new Rectangle2D.Double(
+ rectangle.x - (bufferedImage.getWidth() - rectangle.width) / 2d,
+ rectangle.y - (bufferedImage.getHeight() - rectangle.height) / 2d,
+ bufferedImage.getWidth(),
+ bufferedImage.getHeight());
+ fireUndoableEditHappened(
+ new TransformRestoreEdit(SVGImageFigure.this, geometry, getTransformRestoreData()));
+ changed();
+ }
+
+ private void actionsPerformed2(){
+ Object geometry = getTransformRestoreData();
+ willChange();
+ double newHeight = bufferedImage.getHeight() * rectangle.width / bufferedImage.getWidth();
+ rectangle = new Rectangle2D.Double(rectangle.x, rectangle.y - (newHeight - rectangle.height) / 2d, rectangle.width, newHeight);
+ fireUndoableEditHappened(
+ new TransformRestoreEdit(SVGImageFigure.this, geometry, getTransformRestoreData()));
+ changed();
+ }
+ private void actionsPerformed3(){
+ Object geometry = getTransformRestoreData();
+ willChange();
+ double newWidth = bufferedImage.getWidth() * rectangle.height / bufferedImage.getHeight();
+ rectangle = new Rectangle2D.Double(rectangle.x - (newWidth - rectangle.width) / 2d, rectangle.y, newWidth, rectangle.height);
+ fireUndoableEditHappened(
+ new TransformRestoreEdit(SVGImageFigure.this, geometry, getTransformRestoreData()));
+ changed();
+
+ }
+
+
// CONNECTING
// COMPOSITE FIGURES
// CLONING
@Override
public SVGImageFigure clone() {
- SVGImageFigure that = (SVGImageFigure) super.clone();
- that.rectangle = (Rectangle2D.Double) this.rectangle.clone();
- that.cachedTransformedShape = null;
- that.cachedHitShape = null;
- return that;
+ SVGImageFigure copy = (SVGImageFigure) super.clone();
+ copy.rectangle = (Rectangle2D.Double) this.rectangle.clone();
+ copy.cachedTransformedShape = null;
+ copy.cachedHitShape = null;
+ return copy;
}
@Override
@@ -361,11 +363,10 @@ public void invalidate() {
* imageData array instead of cloning it. Do not modify the imageData
* array after invoking this method.
*
- *
- * @param imageData The image data. If this is null, a buffered image must
- * be provided.
+ * @param imageData The image data. If this is null, a buffered image must
+ * be provided.
* @param bufferedImage An image constructed from the imageData. If this
- * is null, imageData must be provided.
+ * is null, imageData must be provided.
*/
@Override
public void setImage(byte[] imageData, BufferedImage bufferedImage) {
@@ -409,10 +410,9 @@ public void setBufferedImage(BufferedImage image) {
@Override
public BufferedImage getBufferedImage() {
if (bufferedImage == null && imageData != null) {
- //System.out.println("recreateing bufferedImage");
try {
bufferedImage = ImageIO.read(new ByteArrayInputStream(imageData));
- } catch (Throwable e) {
+ } catch (IOException e) {
e.printStackTrace();
// If we can't create a buffered image from the image data,
// there is no use to keep the image data and try again, so
@@ -452,16 +452,13 @@ public byte[] getImageData() {
@Override
public void loadImage(File file) throws IOException {
- InputStream in = new FileInputStream(file);
- try {
+ try (InputStream in = Files.newInputStream(file.toPath())) {
loadImage(in);
- } catch (Throwable t) {
+ } catch (IOException t) {
ResourceBundleUtil labels = ResourceBundleUtil.getBundle("org.jhotdraw.draw.Labels");
IOException e = new IOException(labels.getFormatted("file.failedToLoadImage.message", file.getName()));
e.initCause(t);
throw e;
- } finally {
- in.close();
}
}
@@ -476,7 +473,7 @@ public void loadImage(InputStream in) throws IOException {
BufferedImage img;
try {
img = ImageIO.read(new ByteArrayInputStream(baos.toByteArray()));
- } catch (Throwable t) {
+ } catch (IOException t) {
img = null;
}
if (img == null) {
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/figures/SVGRectFigure.java b/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/figures/SVGRectFigure.java
index d1ba6eae5..e3ebda659 100644
--- a/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/figures/SVGRectFigure.java
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/figures/SVGRectFigure.java
@@ -10,6 +10,7 @@
import java.awt.*;
import java.awt.geom.*;
import java.util.*;
+
import org.jhotdraw.draw.*;
import static org.jhotdraw.draw.AttributeKeys.FILL_COLOR;
import static org.jhotdraw.draw.AttributeKeys.STROKE_CAP;
@@ -24,6 +25,7 @@
import org.jhotdraw.geom.GrowStroke;
import org.jhotdraw.samples.svg.Gradient;
import org.jhotdraw.samples.svg.SVGAttributeKeys;
+
import static org.jhotdraw.samples.svg.SVGAttributeKeys.*;
/**
@@ -35,14 +37,10 @@
public class SVGRectFigure extends SVGAttributedFigure implements SVGFigure {
private static final long serialVersionUID = 1L;
- /**
- * Identifies the {@code arcWidth} JavaBeans property.
- */
- public static final String ARC_WIDTH_PROPERTY = "arcWidth";
- /**
- * Identifies the {@code arcHeight} JavaBeans property.
- */
- public static final String ARC_HEIGHT_PROPERTY = "arcHeight";
+
+ private static final String ARC_WIDTH_PROPERTY = "arcWidth";
+
+ private static final String ARC_HEIGHT_PROPERTY = "arcHeight";
/**
* The variable acv is used for generating the locations of the control
* points for the rounded rectangle using path.curveTo.
@@ -57,9 +55,8 @@ public class SVGRectFigure extends SVGAttributedFigure implements SVGFigure {
double cv = 4.0 / 3.0 * a * b / c;
ACV = (1.0 - cv);
}
- /**
- */
- private RoundRectangle2D.Double roundrect;
+
+ protected RoundRectangle2D.Double roundrect;
/**
* This is used to perform faster drawing.
*/
@@ -69,9 +66,6 @@ public class SVGRectFigure extends SVGAttributedFigure implements SVGFigure {
*/
private transient Shape cachedHitShape;
- /**
- * Creates a new instance.
- */
public SVGRectFigure() {
this(0, 0, 0, 0);
}
@@ -80,13 +74,15 @@ public SVGRectFigure(double x, double y, double width, double height) {
this(x, y, width, height, 0, 0);
}
- public SVGRectFigure(double x, double y, double width, double height, double rx, double ry) {
- roundrect = new RoundRectangle2D.Double(x, y, width, height, rx, ry);
+ public SVGRectFigure(double x, double y, double width, double height, double arcWidth, double arcHeight) {
+ roundrect = new RoundRectangle2D.Double(x, y, width, height, arcWidth, arcHeight);
SVGAttributeKeys.setDefaults(this);
setConnectable(false);
}
- // DRAWING
+ /**
+ * Drawing
+ */
@Override
protected void drawFill(Graphics2D g) {
if (getArcHeight() == 0d && getArcWidth() == 0d) {
@@ -96,41 +92,51 @@ protected void drawFill(Graphics2D g) {
}
}
+
@Override
protected void drawStroke(Graphics2D g) {
if (roundrect.archeight == 0 && roundrect.arcwidth == 0) {
g.draw(roundrect.getBounds2D());
} else {
- // We have to generate the path for the round rectangle manually,
- // because the path of a Java RoundRectangle is drawn counter clockwise
- // whereas an SVG rect needs to be drawn clockwise.
- Path2D.Double p = new Path2D.Double();
- double aw = roundrect.arcwidth / 2d;
- double ah = roundrect.archeight / 2d;
- p.moveTo((roundrect.x + aw), (float) roundrect.y);
- p.lineTo((roundrect.x + roundrect.width - aw), (float) roundrect.y);
- p.curveTo((roundrect.x + roundrect.width - aw * ACV), (float) roundrect.y,
- (roundrect.x + roundrect.width), (float) (roundrect.y + ah * ACV),
- (roundrect.x + roundrect.width), (roundrect.y + ah));
- p.lineTo((roundrect.x + roundrect.width), (roundrect.y + roundrect.height - ah));
- p.curveTo(
- (roundrect.x + roundrect.width), (roundrect.y + roundrect.height - ah * ACV),
- (roundrect.x + roundrect.width - aw * ACV), (roundrect.y + roundrect.height),
- (roundrect.x + roundrect.width - aw), (roundrect.y + roundrect.height));
- p.lineTo((roundrect.x + aw), (roundrect.y + roundrect.height));
- p.curveTo((roundrect.x + aw * ACV), (roundrect.y + roundrect.height),
- (roundrect.x), (roundrect.y + roundrect.height - ah * ACV),
- (float) roundrect.x, (roundrect.y + roundrect.height - ah));
- p.lineTo((float) roundrect.x, (roundrect.y + ah));
- p.curveTo((roundrect.x), (roundrect.y + ah * ACV),
- (roundrect.x + aw * ACV), (float) (roundrect.y),
- (float) (roundrect.x + aw), (float) (roundrect.y));
- p.closePath();
- g.draw(p);
+ drawPath(g);
}
}
- // SHAPE AND BOUNDS
+ /**
+ * Path for the round rectangle must be generated manually,
+ * because the path of a Java RoundRectangle is drawn counterclockwise
+ * whereas an SVG rect needs to be drawn clockwise.
+ * @param g
+ */
+ private void drawPath(Graphics2D g) {
+ Path2D.Double p = new Path2D.Double();
+ double aw = roundrect.arcwidth / 2d;
+ double ah = roundrect.archeight / 2d;
+ p.moveTo((roundrect.x + aw), (float) roundrect.y);
+ p.lineTo((roundrect.x + roundrect.width - aw), (float) roundrect.y);
+ p.curveTo((roundrect.x + roundrect.width - aw * ACV), (float) roundrect.y,
+ (roundrect.x + roundrect.width), (float) (roundrect.y + ah * ACV),
+ (roundrect.x + roundrect.width), (roundrect.y + ah));
+ p.lineTo((roundrect.x + roundrect.width), (roundrect.y + roundrect.height - ah));
+ p.curveTo(
+ (roundrect.x + roundrect.width), (roundrect.y + roundrect.height - ah * ACV),
+ (roundrect.x + roundrect.width - aw * ACV), (roundrect.y + roundrect.height),
+ (roundrect.x + roundrect.width - aw), (roundrect.y + roundrect.height));
+ p.lineTo((roundrect.x + aw), (roundrect.y + roundrect.height));
+ p.curveTo((roundrect.x + aw * ACV), (roundrect.y + roundrect.height),
+ (roundrect.x), (roundrect.y + roundrect.height - ah * ACV),
+ (float) roundrect.x, (roundrect.y + roundrect.height - ah));
+ p.lineTo((float) roundrect.x, (roundrect.y + ah));
+ p.curveTo((roundrect.x), (roundrect.y + ah * ACV),
+ (roundrect.x + aw * ACV), (float) (roundrect.y),
+ (float) (roundrect.x + aw), (float) (roundrect.y));
+ p.closePath();
+ g.draw(p);
+ }
+
+ /**
+ * Shape and Bounds
+ */
public double getX() {
return roundrect.x;
}
@@ -147,42 +153,34 @@ public double getHeight() {
return roundrect.height;
}
- /**
- * Gets the arc width.
- */
public double getArcWidth() {
return roundrect.arcwidth;
}
- /**
- * Gets the arc height.
- */
public double getArcHeight() {
return roundrect.archeight;
}
+ public static String getArcWidthProperty() {
+ return ARC_WIDTH_PROPERTY;
+ }
+
+ public static String getArcHeightProperty() {
+ return ARC_HEIGHT_PROPERTY;
+ }
- /**
- * Sets the arc width.
- */
public void setArcWidth(double newValue) {
double oldValue = roundrect.arcwidth;
roundrect.arcwidth = newValue;
firePropertyChange(ARC_WIDTH_PROPERTY, oldValue, newValue);
}
- /**
- * Sets the arc height.
- */
public void setArcHeight(double newValue) {
double oldValue = roundrect.archeight;
roundrect.archeight = newValue;
firePropertyChange(ARC_HEIGHT_PROPERTY, oldValue, newValue);
}
- /**
- * Convenience method for setting both the arc width and the arc height.
- */
- public void setArc(double width, double height) {
+ public void setBothArcs(double width, double height) {
setArcWidth(width);
setArcHeight(height);
}
@@ -214,9 +212,6 @@ public Rectangle2D.Double getDrawingArea() {
return r;
}
- /**
- * Checks if a Point2D.Double is inside the figure.
- */
@Override
public boolean contains(Point2D.Double p) {
return getHitShape().contains(p);
@@ -252,29 +247,22 @@ private Shape getTransformedShape() {
}
private Shape getHitShape() {
- if (cachedHitShape == null) {
- if (get(FILL_COLOR) != null || get(FILL_GRADIENT) != null) {
- cachedHitShape = new GrowStroke(
- (float) SVGAttributeKeys.getStrokeTotalWidth(this, 1.0) / 2f,
- (float) SVGAttributeKeys.getStrokeTotalMiterLimit(this, 1.0)).createStrokedShape(getTransformedShape());
- } else {
- cachedHitShape = SVGAttributeKeys.getHitStroke(this, 1.0).createStrokedShape(getTransformedShape());
- }
+ if (cachedHitShape != null) {
+ return cachedHitShape;
+ }
+ if (get(FILL_COLOR) != null || get(FILL_GRADIENT) != null) {
+ return cachedHitShape = new GrowStroke(
+ (float) AttributeKeys.getStrokeTotalWidth(this, 1.0) / 2f,
+ (float) AttributeKeys.getStrokeTotalMiterLimit(this, 1.0)).createStrokedShape(getTransformedShape());
+ } else {
+ return cachedHitShape = AttributeKeys.getHitStroke(this, 1.0).createStrokedShape(getTransformedShape());
}
- return cachedHitShape;
}
- /**
- * Transforms the figure.
- *
- * @param tx The transformation.
- */
@Override
public void transform(AffineTransform tx) {
invalidateTransformedShape();
- if (get(TRANSFORM) != null
- || // (tx.getType() & (AffineTransform.TYPE_TRANSLATION | AffineTransform.TYPE_MASK_SCALE)) != tx.getType()) {
- (tx.getType() & (AffineTransform.TYPE_TRANSLATION)) != tx.getType()) {
+ if (get(TRANSFORM) != null || (tx.getType() & (AffineTransform.TYPE_TRANSLATION)) != tx.getType()) {
if (get(TRANSFORM) == null) {
set(TRANSFORM, (AffineTransform) tx.clone());
} else {
@@ -283,23 +271,24 @@ public void transform(AffineTransform tx) {
set(TRANSFORM, t);
}
} else {
- Point2D.Double anchor = getStartPoint();
- Point2D.Double lead = getEndPoint();
- setBounds(
- (Point2D.Double) tx.transform(anchor, anchor),
- (Point2D.Double) tx.transform(lead, lead));
- if (get(FILL_GRADIENT) != null
- && !get(FILL_GRADIENT).isRelativeToFigureBounds()) {
- Gradient g = FILL_GRADIENT.getClone(this);
- g.transform(tx);
- set(FILL_GRADIENT, g);
- }
- if (get(STROKE_GRADIENT) != null
- && !get(STROKE_GRADIENT).isRelativeToFigureBounds()) {
- Gradient g = STROKE_GRADIENT.getClone(this);
- g.transform(tx);
- set(STROKE_GRADIENT, g);
- }
+ executeTransform(tx);
+ }
+ }
+ private void executeTransform(AffineTransform tx){
+ Point2D.Double anchor = getStartPoint();
+ Point2D.Double lead = getEndPoint();
+ setBounds(
+ (Point2D.Double) tx.transform(anchor, anchor),
+ (Point2D.Double) tx.transform(lead, lead));
+ if (get(FILL_GRADIENT) != null && !get(FILL_GRADIENT).isRelativeToFigureBounds()) {
+ Gradient g = FILL_GRADIENT.getClone(this);
+ g.transform(tx);
+ set(FILL_GRADIENT, g);
+ }
+ if (get(STROKE_GRADIENT) != null && !get(STROKE_GRADIENT).isRelativeToFigureBounds()) {
+ Gradient g = STROKE_GRADIENT.getClone(this);
+ g.transform(tx);
+ set(STROKE_GRADIENT, g);
}
}
@@ -322,10 +311,12 @@ public Object getTransformRestoreData() {
STROKE_GRADIENT.getClone(this)};
}
- // EDITING
+ /**
+ * Editing
+ */
@Override
public Collection createHandles(int detailLevel) {
- LinkedList handles = new LinkedList();
+ LinkedList handles = new LinkedList<>();
switch (detailLevel % 2) {
case -1: // Mouse hover handles
handles.add(new BoundsOutlineHandle(this, false, true));
@@ -339,12 +330,14 @@ public Collection createHandles(int detailLevel) {
TransformHandleKit.addTransformHandles(this, handles);
break;
default:
- break;
+ assert false;
}
return handles;
}
- // CLONING
+ /**
+ * Cloning
+ */
@Override
public SVGRectFigure clone() {
SVGRectFigure that = (SVGRectFigure) super.clone();
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/figures/SVGRectRadiusHandle.java b/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/figures/SVGRectRadiusHandle.java
index 5655cf070..8544e9a36 100644
--- a/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/figures/SVGRectRadiusHandle.java
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/figures/SVGRectRadiusHandle.java
@@ -11,7 +11,7 @@
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.geom.*;
-import org.jhotdraw.draw.*;
+
import static org.jhotdraw.draw.AttributeKeys.TRANSFORM;
import org.jhotdraw.draw.event.CompositeFigureEdit;
import org.jhotdraw.draw.handle.AbstractHandle;
@@ -95,7 +95,7 @@ public void trackStep(Point anchor, Point lead, int modifiersEx) {
}
}
Rectangle2D.Double r = owner.getBounds();
- owner.setArc(
+ owner.setBothArcs(
Math.min(owner.getWidth(), Math.max(0, p.x - r.x)),
Math.min(owner.getHeight(), Math.max(0, p.y - r.y)));
owner.changed();
@@ -111,8 +111,8 @@ public void trackEnd(Point anchor, Point lead, int modifiersEx) {
CompositeFigureEdit edit = new CompositeFigureEdit(svgRect, labels.getString("attribute.roundRectRadius"));
edit.setVerbose(true);
fireUndoableEditHappened(edit);
- fireUndoableEditHappened(new PropertyChangeEdit(svgRect, SVGRectFigure.ARC_WIDTH_PROPERTY, oldValue.width, newValue.width));
- fireUndoableEditHappened(new PropertyChangeEdit(svgRect, SVGRectFigure.ARC_HEIGHT_PROPERTY, oldValue.height, newValue.height));
+ fireUndoableEditHappened(new PropertyChangeEdit(svgRect, SVGRectFigure.getArcWidthProperty(), oldValue.width, newValue.width));
+ fireUndoableEditHappened(new PropertyChangeEdit(svgRect, SVGRectFigure.getArcHeightProperty(), oldValue.height, newValue.height));
fireUndoableEditHappened(edit);
}
@@ -145,14 +145,14 @@ public void keyPressed(KeyEvent evt) {
}
if (!newArc.equals(oldArc)) {
owner.willChange();
- owner.setArc(newArc.width, newArc.height);
+ owner.setBothArcs(newArc.width, newArc.height);
owner.changed();
ResourceBundleUtil labels
= ResourceBundleUtil.getBundle("org.jhotdraw.draw.Labels");
CompositeFigureEdit edit = new CompositeFigureEdit(owner, labels.getString("attribute.roundRectRadius"));
fireUndoableEditHappened(edit);
- fireUndoableEditHappened(new PropertyChangeEdit(owner, SVGRectFigure.ARC_WIDTH_PROPERTY, oldArc.width, newArc.width));
- fireUndoableEditHappened(new PropertyChangeEdit(owner, SVGRectFigure.ARC_HEIGHT_PROPERTY, oldArc.height, newArc.height));
+ fireUndoableEditHappened(new PropertyChangeEdit(owner, SVGRectFigure.getArcWidthProperty(), oldArc.width, newArc.width));
+ fireUndoableEditHappened(new PropertyChangeEdit(owner, SVGRectFigure.getArcHeightProperty(), oldArc.height, newArc.height));
fireUndoableEditHappened(edit);
}
}
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/figures/SVGTextFigure.java b/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/figures/SVGTextFigure.java
index a96bb5211..6e88bc8fd 100644
--- a/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/figures/SVGTextFigure.java
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/figures/SVGTextFigure.java
@@ -7,6 +7,7 @@
*/
package org.jhotdraw.samples.svg.figures;
+import dk.sdu.mmmi.featuretracer.lib.FeatureEntryPoint;
import org.jhotdraw.draw.figure.TextHolderFigure;
import java.awt.*;
import java.awt.font.*;
@@ -67,15 +68,19 @@ public SVGTextFigure() {
this("Text");
}
+ @FeatureEntryPoint("SVGTextFigure")
public SVGTextFigure(String text) {
setText(text);
SVGAttributeKeys.setDefaults(this);
setConnectable(false);
}
- // DRAWING
+
@Override
protected void drawText(java.awt.Graphics2D g) {
+ /*
+ This method is empty for some reason
+ */
}
@Override
@@ -121,7 +126,7 @@ public Rectangle2D.Double getBounds() {
text = " ";
}
FontRenderContext frc = getFontRenderContext();
- HashMap textAttributes = new HashMap();
+ HashMap textAttributes = new HashMap<>();
textAttributes.put(TextAttribute.FONT, getFont());
if (get(FONT_UNDERLINE)) {
textAttributes.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
@@ -186,7 +191,7 @@ private Shape getTextShape() {
text = " ";
}
FontRenderContext frc = getFontRenderContext();
- HashMap textAttributes = new HashMap();
+ HashMap textAttributes = new HashMap<>();
textAttributes.put(TextAttribute.FONT, getFont());
if (get(FONT_UNDERLINE)) {
textAttributes.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
@@ -205,10 +210,7 @@ private Shape getTextShape() {
break;
}
tx.rotate(rotates[0]);
- /*
- if (get(TRANSFORM) != null) {
- tx.preConcatenate(get(TRANSFORM));
- }*/
+
cachedTextShape = tx.createTransformedShape(textLayout.getOutline(tx));
cachedTextShape = textLayout.getOutline(tx);
}
@@ -296,11 +298,11 @@ public String getText() {
@Override
public void set(AttributeKey key, T newValue) {
- if (key.equals(SVGAttributeKeys.TRANSFORM)
- || key.equals(SVGAttributeKeys.FONT_FACE)
- || key.equals(SVGAttributeKeys.FONT_BOLD)
- || key.equals(SVGAttributeKeys.FONT_ITALIC)
- || key.equals(SVGAttributeKeys.FONT_SIZE)) {
+ if (key.equals(AttributeKeys.TRANSFORM)
+ || key.equals(AttributeKeys.FONT_FACE)
+ || key.equals(AttributeKeys.FONT_BOLD)
+ || key.equals(AttributeKeys.FONT_ITALIC)
+ || key.equals(AttributeKeys.FONT_SIZE)) {
invalidate();
}
super.set(key, newValue);
@@ -325,30 +327,26 @@ public void setEditable(boolean b) {
@Override
public int getTextColumns() {
- //return (getText() == null) ? 4 : Math.min(getText().length(), 4);
return 4;
}
@Override
public Font getFont() {
- return SVGAttributeKeys.getFont(this);
+ return AttributeKeys.getFont(this);
}
@Override
public Color getTextColor() {
return get(FILL_COLOR);
- // return get(TEXT_COLOR);
}
@Override
public Color getFillColor() {
return get(FILL_COLOR) == null || get(FILL_COLOR).equals(Color.white) ? Color.black : Color.WHITE;
- // return get(FILL_COLOR);
}
@Override
public void setFontSize(float size) {
- // put(FONT_SIZE, new Double(size));
Point2D.Double p = new Point2D.Double(0, size);
AffineTransform tx = get(TRANSFORM);
if (tx != null) {
@@ -366,7 +364,6 @@ public void setFontSize(float size) {
@Override
public float getFontSize() {
- // return get(FONT_SIZE).floatValue();
Point2D.Double p = new Point2D.Double(0, get(FONT_SIZE));
AffineTransform tx = get(TRANSFORM);
if (tx != null) {
@@ -374,12 +371,6 @@ public float getFontSize() {
Point2D.Double p0 = new Point2D.Double(0, 0);
tx.transform(p0, p0);
p.y -= p0.y;
- /*
- try {
- tx.inverseTransform(p, p);
- } catch (NoninvertibleTransformException ex) {
- ex.printStackTrace();
- }*/
}
return (float) Math.abs(p.y);
}
@@ -397,12 +388,13 @@ public void invalidate() {
@Override
public Dimension2DDouble getPreferredSize() {
Rectangle2D.Double b = getBounds();
+ assert b.width > 0 && b.height > 0;
return new Dimension2DDouble(b.width, b.height);
}
@Override
public Collection createHandles(int detailLevel) {
- LinkedList handles = new LinkedList();
+ LinkedList handles = new LinkedList<>();
switch (detailLevel % 2) {
case -1: // Mouse hover handles
handles.add(new BoundsOutlineHandle(this, false, true));
@@ -419,6 +411,8 @@ public Collection createHandles(int detailLevel) {
case 1:
TransformHandleKit.addTransformHandles(this, handles);
break;
+ default:
+ break;
}
return handles;
}
@@ -432,9 +426,9 @@ public Collection createHandles(int detailLevel) {
@Override
public Tool getTool(Point2D.Double p) {
if (isEditable() && contains(p)) {
- TextEditingTool tool = new TextEditingTool(this);
- return tool;
+ return new TextEditingTool(this);
}
+
return null;
}
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/io/DefaultSVGFigureFactory.java b/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/io/DefaultSVGFigureFactory.java
index fe29d444b..53b02d372 100644
--- a/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/io/DefaultSVGFigureFactory.java
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/main/java/org/jhotdraw/samples/svg/io/DefaultSVGFigureFactory.java
@@ -46,7 +46,7 @@ public DefaultSVGFigureFactory() {
public Figure createRect(double x, double y, double w, double h, double rx, double ry, Map, Object> a) {
SVGRectFigure figure = new SVGRectFigure();
figure.setBounds(new Point2D.Double(x, y), new Point2D.Double(x + w, y + h));
- figure.setArc(rx, ry);
+ figure.setBothArcs(rx, ry);
figure.setAttributes(a);
return figure;
}
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/main/resources/META-INF/aop.xml b/jhotdraw-samples/jhotdraw-samples-misc/src/main/resources/META-INF/aop.xml
index bd42481a5..d5624fc77 100644
--- a/jhotdraw-samples/jhotdraw-samples-misc/src/main/resources/META-INF/aop.xml
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/main/resources/META-INF/aop.xml
@@ -6,6 +6,9 @@
+
+
+
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/BasicEdit/GivenDelete.java b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/BasicEdit/GivenDelete.java
new file mode 100644
index 000000000..d096ba6cf
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/BasicEdit/GivenDelete.java
@@ -0,0 +1,25 @@
+package org.jhotdraw.samples.svg.BasicEdit;
+
+import com.tngtech.jgiven.Stage;
+import com.tngtech.jgiven.annotation.ProvidedScenarioState;
+import org.jhotdraw.draw.Drawing;
+import org.jhotdraw.draw.QuadTreeDrawing;
+import org.jhotdraw.samples.svg.figures.SVGRectFigure;
+
+public class GivenDelete extends Stage {
+
+ @ProvidedScenarioState
+ Drawing drawing;
+
+ @ProvidedScenarioState
+ SVGRectFigure rect;
+
+
+ public GivenDelete EmptyDrawing() {
+ this.drawing = new QuadTreeDrawing();
+ rect = new SVGRectFigure(10, 10, 50, 100);
+ drawing.add(rect);
+ return this;
+ }
+
+}
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/BasicEdit/ThenDelete.java b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/BasicEdit/ThenDelete.java
new file mode 100644
index 000000000..7fa9b2481
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/BasicEdit/ThenDelete.java
@@ -0,0 +1,25 @@
+package org.jhotdraw.samples.svg.BasicEdit;
+
+import com.tngtech.jgiven.Stage;
+import com.tngtech.jgiven.annotation.ProvidedScenarioState;
+import org.jhotdraw.samples.svg.figures.SVGRectFigure;
+
+
+
+import static org.junit.Assert.*;
+
+public class ThenDelete extends Stage {
+
+
+ @ProvidedScenarioState
+ SVGRectFigure rect;
+
+ public ThenDelete theDrawingIsDeleted() {
+ assertNotNull(rect);
+ return this;
+ }
+
+
+
+
+}
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/BasicEdit/WhenDelete.java b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/BasicEdit/WhenDelete.java
new file mode 100644
index 000000000..8df918852
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/BasicEdit/WhenDelete.java
@@ -0,0 +1,20 @@
+package org.jhotdraw.samples.svg.BasicEdit;
+
+import com.tngtech.jgiven.Stage;
+import com.tngtech.jgiven.annotation.ProvidedScenarioState;
+import org.jhotdraw.draw.Drawing;
+import static org.junit.Assert.*;
+
+public class WhenDelete extends Stage {
+
+ @ProvidedScenarioState
+ Drawing drawing;
+
+
+ public WhenDelete deletingTheDrawing() {
+ assertNotNull(this.drawing);
+ //rect.getActions().add(new DeleteAction());
+ return this;
+ }
+}
+
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/DeleteDrawingBDDTest.java b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/DeleteDrawingBDDTest.java
new file mode 100644
index 000000000..cd2a79425
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/DeleteDrawingBDDTest.java
@@ -0,0 +1,20 @@
+package org.jhotdraw.samples.svg;
+
+import com.tngtech.jgiven.junit.ScenarioTest;
+import org.jhotdraw.samples.svg.BasicEdit.GivenDelete;
+import org.jhotdraw.samples.svg.BasicEdit.WhenDelete;
+import org.jhotdraw.samples.svg.BasicEdit.ThenDelete;
+import org.junit.Test;
+
+public class DeleteDrawingBDDTest extends ScenarioTest {
+ @Test
+ public void deleteDrawing() {
+ given().EmptyDrawing();
+ when().deletingTheDrawing();
+ then().theDrawingIsDeleted();
+ }
+
+
+
+
+}
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/ImageFeatureBehaviourTest.java b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/ImageFeatureBehaviourTest.java
new file mode 100644
index 000000000..53a2b5610
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/ImageFeatureBehaviourTest.java
@@ -0,0 +1,25 @@
+package org.jhotdraw.samples.svg;
+import org.jhotdraw.samples.svg.jgivenstages.GivenImage;
+import org.jhotdraw.samples.svg.jgivenstages.ThenImage;
+import org.jhotdraw.samples.svg.jgivenstages.WhenImage;
+import org.junit.Test;
+import com.tngtech.jgiven.junit.ScenarioTest;
+
+public class ImageFeatureBehaviourTest extends ScenarioTest{
+
+ @Test
+ public void drawImage() {
+ given().anEmptyDrawing();
+ when().anImageIsDrawn();
+ then().theDrawingCointansTheDrawnImage();
+ }
+
+ @Test
+ public void resizeImage() {
+ given().anEmptyDrawing()
+ .and().anImageIsAdded();
+ when().theImageIsResized();
+ then().theImageHasTheNewSize();
+ }
+
+}
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/TextToolBDDTest.java b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/TextToolBDDTest.java
new file mode 100644
index 000000000..c53bf81da
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/TextToolBDDTest.java
@@ -0,0 +1,23 @@
+package org.jhotdraw.samples.svg;
+
+import com.tngtech.jgiven.junit.ScenarioTest;
+import org.jhotdraw.samples.svg.bdd.GivenTextFigureTest;
+import org.jhotdraw.samples.svg.bdd.ThenTextFigureTest;
+import org.jhotdraw.samples.svg.bdd.WhenTextFigureTest;
+import org.junit.Test;
+
+public class TextToolBDDTest extends ScenarioTest {
+ @Test
+ public void drawTexTool() {
+ given().anEmptyDrawing();
+ when().aTextToolIsDrawn();
+ then().theDrawingContainsATextBox();
+ }
+
+ @Test
+ public void rotateTextTool() {
+ given().aDrawing().and().aText();
+ when().theTextToolIsRotated();
+ then().theTextBoxHasTheCorrectRotation();
+ }
+}
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/bdd/GivenTextFigureTest.java b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/bdd/GivenTextFigureTest.java
new file mode 100644
index 000000000..2b726e6a2
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/bdd/GivenTextFigureTest.java
@@ -0,0 +1,27 @@
+package org.jhotdraw.samples.svg.bdd;
+
+import com.tngtech.jgiven.Stage;
+import com.tngtech.jgiven.annotation.ProvidedScenarioState;
+import org.jhotdraw.draw.Drawing;
+import org.jhotdraw.draw.QuadTreeDrawing;
+import org.jhotdraw.samples.svg.figures.SVGTextFigure;
+
+public class GivenTextFigureTest extends Stage {
+ @ProvidedScenarioState
+ Drawing drawing;
+
+ public GivenTextFigureTest anEmptyDrawing() {
+ this.drawing = new QuadTreeDrawing();
+ return this;
+ }
+
+ public GivenTextFigureTest aDrawing() {
+ this.drawing = new QuadTreeDrawing();
+ return this;
+ }
+
+ public GivenTextFigureTest aText() {
+ this.drawing.add(new SVGTextFigure());
+ return this;
+ }
+}
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/bdd/ThenTextFigureTest.java b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/bdd/ThenTextFigureTest.java
new file mode 100644
index 000000000..a8c0f826b
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/bdd/ThenTextFigureTest.java
@@ -0,0 +1,35 @@
+package org.jhotdraw.samples.svg.bdd;
+
+import com.tngtech.jgiven.Stage;
+import com.tngtech.jgiven.annotation.ScenarioState;
+import org.jhotdraw.draw.Drawing;
+import org.jhotdraw.draw.figure.Figure;
+import org.jhotdraw.samples.svg.figures.SVGTextFigure;
+
+import java.util.List;
+
+import static com.tngtech.jgiven.impl.util.AssertionUtil.assertNotNull;
+import static org.junit.Assert.*;
+
+public class ThenTextFigureTest extends Stage {
+ @ScenarioState
+ Drawing drawing;
+
+ public ThenTextFigureTest theDrawingContainsATextBox() {
+ List figures = drawing.getFiguresFrontToBack();
+ assertTrue(figures.stream().anyMatch(figure -> figure instanceof SVGTextFigure));
+ return this;
+ }
+
+ public ThenTextFigureTest theTextBoxHasTheCorrectRotation() {
+ assertNotNull(drawing);
+ List figures = drawing.getFiguresFrontToBack();
+ assertEquals(1, figures.size());
+ Figure figure = figures.get(0);
+ assertTrue(figure instanceof SVGTextFigure);
+ SVGTextFigure textFigure = (SVGTextFigure) figure;
+ double[] rotation = textFigure.getRotates();
+ assertArrayEquals(new double[]{90}, rotation, 0.1);
+ return this;
+ }
+}
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/bdd/WhenTextFigureTest.java b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/bdd/WhenTextFigureTest.java
new file mode 100644
index 000000000..e07ef6ae4
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/bdd/WhenTextFigureTest.java
@@ -0,0 +1,35 @@
+package org.jhotdraw.samples.svg.bdd;
+
+import com.tngtech.jgiven.Stage;
+import com.tngtech.jgiven.annotation.ScenarioState;
+import org.jhotdraw.draw.Drawing;
+import org.jhotdraw.draw.figure.Figure;
+import org.jhotdraw.samples.svg.figures.SVGTextFigure;
+
+import java.util.List;
+
+import static com.tngtech.jgiven.impl.util.AssertionUtil.assertNotNull;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class WhenTextFigureTest extends Stage {
+ @ScenarioState
+ Drawing drawing;
+
+ public WhenTextFigureTest aTextToolIsDrawn() {
+ assertNotNull(drawing);
+ drawing.add(new SVGTextFigure());
+ return this;
+ }
+
+ public WhenTextFigureTest theTextToolIsRotated() {
+ assertNotNull(drawing);
+ List figures = drawing.getFiguresFrontToBack();
+ assertEquals(figures.size(), 1);
+ Figure figure = figures.get(0);
+ assertTrue(figure instanceof SVGTextFigure);
+ SVGTextFigure textFigure = (SVGTextFigure) figure;
+ textFigure.setRotates(new double[]{90});
+ return this;
+ }
+}
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/SVGEllipseFigureBDDTest.java b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/SVGEllipseFigureBDDTest.java
new file mode 100644
index 000000000..da3843e16
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/SVGEllipseFigureBDDTest.java
@@ -0,0 +1,18 @@
+package org.jhotdraw.samples.svg.figures;
+
+import com.tngtech.jgiven.junit.ScenarioTest;
+import org.jhotdraw.samples.svg.figures.jgivenstages.GivenEllipseDrawing;
+import org.jhotdraw.samples.svg.figures.jgivenstages.ThenEllipseDrawing;
+import org.jhotdraw.samples.svg.figures.jgivenstages.WhenEllipseDrawing;
+import org.junit.Test;
+
+public class SVGEllipseFigureBDDTest extends ScenarioTest {
+ @Test
+ public void testEllipseDrawing() {
+ given().the_user_has_selected_the_ellipse_drawing_tool();
+ when().the_user_clicks_and_drags_the_mouse_to_create_an_ellipse_on_the_drawing_canvas();
+ then().an_ellipse_shape_should_be_created_with_the_specified_dimensions();
+ }
+
+
+}
\ No newline at end of file
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/SVGEllipseFigureTest.java b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/SVGEllipseFigureTest.java
new file mode 100644
index 000000000..41f0bc65b
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/SVGEllipseFigureTest.java
@@ -0,0 +1,70 @@
+package org.jhotdraw.samples.svg.figures;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+
+import static org.jhotdraw.draw.AttributeKeys.TRANSFORM;
+import static org.junit.Assert.*;
+
+public class SVGEllipseFigureTest {
+
+ private SVGEllipseFigure ellipseFigure;
+
+ @Before
+ public void setUp() {
+ // Initialize a new SVGEllipseFigure for each test method
+ ellipseFigure = new SVGEllipseFigure(10, 10, 30, 20);
+ }
+
+ @After
+ public void tearDown() {
+ // Set the SVGEllipseFigure to null after each test method
+ ellipseFigure = null;
+ }
+
+ @Test
+ public void testTransformBestCase() {
+ // Test the transform() method with a best-case scenario
+ AffineTransform tx = AffineTransform.getTranslateInstance(5, 5);
+ ellipseFigure.transform(tx);
+
+ // Verify that the figure has been transformed correctly
+ Rectangle2D.Double bounds = ellipseFigure.getBounds();
+ assertEquals(15.0, bounds.getX(), 0.01);
+ assertEquals(15.0, bounds.getY(), 0.01);
+
+ }
+
+ @Test
+ public void testTransformNull() {
+ // Test the transform() method with a null argument
+ AffineTransform prevTransform = ellipseFigure.get(TRANSFORM);
+ // Assert that the figure has no transform before the transform() method is called
+ assertNull(prevTransform);
+
+ }
+
+ @Test
+ public void testTransformStackable() {
+ // Made another ellipseFigure to test if the transform() method is stackable
+ SVGEllipseFigure ellipseFigure2 = new SVGEllipseFigure(10, 10, 35, 25);
+ // Adds 5 to the x and y coordinates of both ellipseFigures
+ AffineTransform tx = AffineTransform.getTranslateInstance(5, 5);
+
+ // Transforms both ellipseFigures
+ ellipseFigure.transform(tx);
+ ellipseFigure2.transform(tx);
+ // Verify that the figure has been transformed correctly
+ Rectangle2D.Double bounds = ellipseFigure.getBounds();
+ Rectangle2D.Double bounds2 = ellipseFigure2.getBounds();
+ assertEquals(15.0, bounds.getX(), 0.01);
+ assertEquals(15.0, bounds.getY(), 0.01);
+ assertEquals(15.0, bounds2.getX(), 0.01);
+ assertEquals(15.0, bounds2.getY(), 0.01);
+
+ }
+}
\ No newline at end of file
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/SVGImageFigureTest.java b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/SVGImageFigureTest.java
new file mode 100644
index 000000000..1c21c268f
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/SVGImageFigureTest.java
@@ -0,0 +1,44 @@
+package org.jhotdraw.samples.svg.figures;
+
+import org.junit.Test;
+import java.awt.geom.AffineTransform;
+import static org.jhotdraw.draw.AttributeKeys.TRANSFORM;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+
+public class SVGImageFigureTest{
+ @Test
+ public void testTransformCanBeApplied() {
+ SVGImageFigure figure = new SVGImageFigure();
+
+ AffineTransform transform = new AffineTransform(5, 10, 5, 10, 5, 10);
+ figure.transform(transform);
+
+ assertEquals(transform, figure.get(TRANSFORM));
+ }
+
+ @Test
+ public void transformShouldSetTransformWhenNoExistingTransform() {
+ // Arrange
+ SVGImageFigure imageFigure = new SVGImageFigure();
+ AffineTransform nonExistingTransform = imageFigure.get(TRANSFORM);
+
+ assertNull(nonExistingTransform);
+ }
+
+ @Test
+ public void transformShouldSetBoundsWhenSpecialConditionIsMet() {
+ SVGImageFigure imageFigure1 = new SVGImageFigure();
+ AffineTransform transform1 = new AffineTransform(2, 1, 2, 1, 2, 1);
+ AffineTransform transform2 = new AffineTransform(1, 2, 1, 2, 1, 2);
+
+ imageFigure1.transform(transform2);
+ imageFigure1.transform(transform1);
+
+ AffineTransform expectedTransform = new AffineTransform(6, 3, 6, 3, 8, 4);
+ assertEquals(expectedTransform, imageFigure1.get(TRANSFORM));
+
+
+ }
+}
\ No newline at end of file
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/SVGRectFigureBDDTest.java b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/SVGRectFigureBDDTest.java
new file mode 100644
index 000000000..d6ead9ed3
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/SVGRectFigureBDDTest.java
@@ -0,0 +1,17 @@
+package org.jhotdraw.samples.svg.figures;
+
+import com.tngtech.jgiven.junit.ScenarioTest;
+import org.jhotdraw.samples.svg.figures.jgivenstages.GivenRectangle;
+import org.jhotdraw.samples.svg.figures.jgivenstages.ThenRectangle;
+import org.jhotdraw.samples.svg.figures.jgivenstages.WhenRectangle;
+import org.junit.Test;
+
+public class SVGRectFigureBDDTest extends ScenarioTest {
+
+ @Test
+ public void drawRectangle() {
+ given().empty_canvas();
+ when().a_rectangle_is_drawn();
+ then().canvas_contains_rectangle();
+ }
+}
\ No newline at end of file
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/SVGRectFigureTest.java b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/SVGRectFigureTest.java
new file mode 100644
index 000000000..01adc33da
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/SVGRectFigureTest.java
@@ -0,0 +1,61 @@
+package org.jhotdraw.samples.svg.figures;
+
+import org.junit.Test;
+
+import java.awt.*;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+public class SVGRectFigureTest {
+ SVGRectFigure svgRectFigure = new SVGRectFigure();
+ Graphics2D mockGraphics2D = mock(Graphics2D.class);
+
+
+ /**
+ * Test the state of the figure after calling drawStroke().
+ * Test for boundary value analysis, as the figure is a branch
+ * if the arcwidth and archeight are 0 using assertEquals().
+ */
+ @Test
+ public void drawStrokeCheckState() {
+ int initialWidth = (int) svgRectFigure.roundrect.width;
+
+ svgRectFigure.roundrect.arcwidth = 0;
+ svgRectFigure.roundrect.archeight = 0;
+
+ svgRectFigure.drawStroke(mockGraphics2D);
+
+ int finalWidth = (int) svgRectFigure.roundrect.width;
+
+ assertEquals(initialWidth, finalWidth);
+ }
+
+ /**
+ * Test that drawStroke() calls Graphics2D.draw() if the figure is a branch.
+ * Test for boundary value analysis, as the figure is a branch if the arcwidth and archeight are 0.
+ */
+ @Test
+ public void drawStrokeIfBranchValue0() {
+ svgRectFigure.roundrect.arcwidth = 0;
+ svgRectFigure.roundrect.archeight = 0;
+
+ svgRectFigure.drawStroke(mockGraphics2D);
+
+ verify(mockGraphics2D, times(1)).draw(any());
+ }
+
+ /**
+ * Test that drawStroke() calls Graphics2D.draw() if the figure is a branch.
+ * Tests else branch of drawStroke(), where values are not 0.
+ */
+ @Test
+ public void drawStrokeElseBranch() {
+ svgRectFigure.roundrect.arcwidth = 1;
+ svgRectFigure.roundrect.archeight = 1;
+
+ svgRectFigure.drawStroke(mockGraphics2D);
+
+ verify(mockGraphics2D, times(1)).draw(any());
+ }
+}
\ No newline at end of file
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/SVGTextFigureTest.java b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/SVGTextFigureTest.java
new file mode 100644
index 000000000..8396841d0
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/SVGTextFigureTest.java
@@ -0,0 +1,43 @@
+package org.jhotdraw.samples.svg.figures;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.awt.geom.Point2D;
+
+import static org.junit.Assert.*;
+
+public class SVGTextFigureTest {
+ SVGTextFigure textFigure;
+
+ @Before
+ public void setUp() throws Exception {
+ textFigure = new SVGTextFigure();
+ }
+
+ @Test
+ public void setRotationTest() {
+ // Arrange
+ double[] rotation = new double[]{90.0};
+
+ // Act
+ textFigure.setRotates(rotation);
+
+ //Assert
+ assertArrayEquals(textFigure.getRotates(), rotation, 0.1);
+ }
+
+ @Test
+ public void moveTest() {
+ // Arrange
+ Point2D.Double[] coordinates = new Point2D.Double[]{
+ new Point2D.Double(100, 100)
+ };
+
+ // Act
+ textFigure.setCoordinates(coordinates);
+
+ //Assert
+ assertArrayEquals(textFigure.getCoordinates(), coordinates);
+ }
+}
\ No newline at end of file
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/jgivenstages/GivenEllipseDrawing.java b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/jgivenstages/GivenEllipseDrawing.java
new file mode 100644
index 000000000..7398f3765
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/jgivenstages/GivenEllipseDrawing.java
@@ -0,0 +1,16 @@
+package org.jhotdraw.samples.svg.figures.jgivenstages;
+
+import com.tngtech.jgiven.Stage;
+import com.tngtech.jgiven.annotation.ProvidedScenarioState;
+import org.jhotdraw.draw.Drawing;
+import org.jhotdraw.draw.QuadTreeDrawing;
+
+public class GivenEllipseDrawing extends Stage {
+
+ @ProvidedScenarioState
+ Drawing drawing;
+
+ public void the_user_has_selected_the_ellipse_drawing_tool() {
+ this.drawing = new QuadTreeDrawing();
+ }
+}
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/jgivenstages/GivenRectangle.java b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/jgivenstages/GivenRectangle.java
new file mode 100644
index 000000000..30aa6ea11
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/jgivenstages/GivenRectangle.java
@@ -0,0 +1,18 @@
+package org.jhotdraw.samples.svg.figures.jgivenstages;
+
+import com.tngtech.jgiven.Stage;
+import com.tngtech.jgiven.annotation.ProvidedScenarioState;
+import org.jhotdraw.draw.DefaultDrawing;
+import org.jhotdraw.draw.Drawing;
+
+
+public class GivenRectangle extends Stage{
+
+ @ProvidedScenarioState
+ Drawing drawing;
+
+ public GivenRectangle empty_canvas(){
+ this.drawing = new DefaultDrawing();
+ return this;
+ }
+}
\ No newline at end of file
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/jgivenstages/ThenEllipseDrawing.java b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/jgivenstages/ThenEllipseDrawing.java
new file mode 100644
index 000000000..020ca3b84
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/jgivenstages/ThenEllipseDrawing.java
@@ -0,0 +1,22 @@
+package org.jhotdraw.samples.svg.figures.jgivenstages;
+
+import com.tngtech.jgiven.Stage;
+import com.tngtech.jgiven.annotation.ProvidedScenarioState;
+import org.jhotdraw.draw.Drawing;
+import org.jhotdraw.draw.figure.Figure;
+import org.jhotdraw.samples.svg.figures.SVGEllipseFigure;
+
+import java.util.List;
+
+import static org.junit.Assert.assertTrue;
+
+public class ThenEllipseDrawing extends Stage {
+
+ @ProvidedScenarioState
+ Drawing drawing;
+
+ public void an_ellipse_shape_should_be_created_with_the_specified_dimensions() {
+ List figures = drawing.getFiguresFrontToBack();
+ assertTrue(figures.stream().anyMatch(figure -> figure instanceof SVGEllipseFigure));
+ }
+}
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/jgivenstages/ThenRectangle.java b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/jgivenstages/ThenRectangle.java
new file mode 100644
index 000000000..c0a81a73c
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/jgivenstages/ThenRectangle.java
@@ -0,0 +1,23 @@
+package org.jhotdraw.samples.svg.figures.jgivenstages;
+
+import com.tngtech.jgiven.Stage;
+import com.tngtech.jgiven.annotation.ScenarioState;
+import org.jhotdraw.draw.Drawing;
+import org.jhotdraw.draw.figure.Figure;
+import org.jhotdraw.samples.svg.figures.SVGRectFigure;
+
+import java.util.List;
+
+import static org.junit.Assert.assertTrue;
+
+public class ThenRectangle extends Stage {
+
+ @ScenarioState
+ Drawing drawing;
+
+ public ThenRectangle canvas_contains_rectangle() {
+ List figure = drawing.getFiguresFrontToBack();
+ assertTrue(figure.stream().anyMatch(f -> f instanceof SVGRectFigure));
+ return this;
+ }
+}
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/jgivenstages/WhenEllipseDrawing.java b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/jgivenstages/WhenEllipseDrawing.java
new file mode 100644
index 000000000..720dd7c98
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/jgivenstages/WhenEllipseDrawing.java
@@ -0,0 +1,18 @@
+package org.jhotdraw.samples.svg.figures.jgivenstages;
+
+import com.tngtech.jgiven.Stage;
+import com.tngtech.jgiven.annotation.ProvidedScenarioState;
+import org.jhotdraw.draw.Drawing;
+import org.jhotdraw.samples.svg.figures.SVGEllipseFigure;
+
+import static org.junit.Assert.assertNotNull;
+
+public class WhenEllipseDrawing extends Stage {
+ @ProvidedScenarioState
+ Drawing drawing;
+
+ public void the_user_clicks_and_drags_the_mouse_to_create_an_ellipse_on_the_drawing_canvas() {
+ assertNotNull(drawing);
+ drawing.add(new SVGEllipseFigure());
+ }
+}
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/jgivenstages/WhenRectangle.java b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/jgivenstages/WhenRectangle.java
new file mode 100644
index 000000000..2e3eab5f3
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/figures/jgivenstages/WhenRectangle.java
@@ -0,0 +1,21 @@
+package org.jhotdraw.samples.svg.figures.jgivenstages;
+
+import com.tngtech.jgiven.Stage;
+import com.tngtech.jgiven.annotation.ScenarioState;
+import org.jhotdraw.draw.Drawing;
+import org.jhotdraw.samples.svg.figures.SVGRectFigure;
+
+import static org.junit.Assert.assertNotNull;
+
+public class WhenRectangle extends Stage {
+
+ @ScenarioState
+ Drawing drawing;
+
+ public WhenRectangle a_rectangle_is_drawn() {
+ assertNotNull(drawing);
+ drawing.add(new SVGRectFigure());
+ return this;
+ }
+
+}
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/jgivenstages/GivenImage.java b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/jgivenstages/GivenImage.java
new file mode 100644
index 000000000..cdb3b1a8d
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/jgivenstages/GivenImage.java
@@ -0,0 +1,22 @@
+package org.jhotdraw.samples.svg.jgivenstages;
+
+import com.tngtech.jgiven.Stage;
+import com.tngtech.jgiven.annotation.ProvidedScenarioState;
+import org.jhotdraw.draw.Drawing;
+import org.jhotdraw.draw.QuadTreeDrawing;
+import org.jhotdraw.samples.svg.figures.SVGImageFigure;
+
+public class GivenImage extends Stage {
+
+ @ProvidedScenarioState
+ Drawing drawing;
+
+ public GivenImage anEmptyDrawing() {
+ this.drawing = new QuadTreeDrawing();
+ return this;
+ }
+ public GivenImage anImageIsAdded() {
+ this.drawing.add(new SVGImageFigure());
+ return this;
+ }
+}
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/jgivenstages/ThenImage.java b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/jgivenstages/ThenImage.java
new file mode 100644
index 000000000..5b1c39e40
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/jgivenstages/ThenImage.java
@@ -0,0 +1,36 @@
+package org.jhotdraw.samples.svg.jgivenstages;
+
+import com.tngtech.jgiven.Stage;
+import com.tngtech.jgiven.annotation.ScenarioState;
+import org.jhotdraw.draw.Drawing;
+import org.jhotdraw.draw.figure.Figure;
+import org.jhotdraw.samples.svg.figures.SVGImageFigure;
+
+import java.awt.geom.Rectangle2D;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+public class ThenImage extends Stage {
+
+ @ScenarioState
+ Drawing drawing;
+
+ public ThenImage theDrawingCointansTheDrawnImage() {
+ List figures = drawing.getFiguresFrontToBack();
+ assertTrue(figures.stream().anyMatch(figure -> figure instanceof SVGImageFigure));
+ return this;
+ }
+
+ public ThenImage theImageHasTheNewSize() {
+ assertNotNull(drawing);
+ List figures = drawing.getFiguresFrontToBack();
+ assertEquals(figures.size(), 1);
+ Figure figure = figures.get(0);
+ assertTrue(figure instanceof SVGImageFigure);
+ SVGImageFigure ellipse = (SVGImageFigure) figure;
+ Rectangle2D bounds = ellipse.getBounds();
+ assertEquals(new Rectangle2D.Double(1, 2, 3, 4), bounds);
+ return this;
+ }
+}
diff --git a/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/jgivenstages/WhenImage.java b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/jgivenstages/WhenImage.java
new file mode 100644
index 000000000..34a5d3852
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples-misc/src/test/java/org/jhotdraw/samples/svg/jgivenstages/WhenImage.java
@@ -0,0 +1,42 @@
+package org.jhotdraw.samples.svg.jgivenstages;
+
+import com.tngtech.jgiven.Stage;
+import com.tngtech.jgiven.annotation.ScenarioState;
+import org.jhotdraw.draw.Drawing;
+import org.jhotdraw.draw.figure.Figure;
+import org.jhotdraw.samples.svg.figures.SVGEllipseFigure;
+import org.jhotdraw.samples.svg.figures.SVGImageFigure;
+
+import java.awt.geom.Point2D;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+public class WhenImage extends Stage {
+
+ @ScenarioState
+ Drawing drawing;
+ public WhenImage anImageIsDrawn(){
+ assertNotNull(drawing);
+ drawing.add(new SVGImageFigure());
+ return this;
+ }
+
+ public WhenImage anEllipseIsDrawn() {
+ assertNotNull(drawing);
+ drawing.add(new SVGEllipseFigure());
+ return this;
+ }
+
+ public WhenImage theImageIsResized() {
+ assertNotNull(drawing);
+ List figures = drawing.getFiguresFrontToBack();
+ assertEquals(figures.size(), 1);
+ Figure figure = figures.get(0);
+ assertTrue(figure instanceof SVGImageFigure);
+ SVGImageFigure ellipse = (SVGImageFigure) figure;
+ ellipse.setBounds(new Point2D.Double(1, 2), new Point2D.Double(4, 6));
+ return this;
+ }
+}
+
diff --git a/jhotdraw-samples/jhotdraw-samples.iml b/jhotdraw-samples/jhotdraw-samples.iml
new file mode 100644
index 000000000..175c0f99a
--- /dev/null
+++ b/jhotdraw-samples/jhotdraw-samples.iml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jhotdraw-utils/jhotdraw-utils.iml b/jhotdraw-utils/jhotdraw-utils.iml
new file mode 100644
index 000000000..05f6ffccf
--- /dev/null
+++ b/jhotdraw-utils/jhotdraw-utils.iml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jhotdraw-xml/jhotdraw-xml.iml b/jhotdraw-xml/jhotdraw-xml.iml
new file mode 100644
index 000000000..20162e571
--- /dev/null
+++ b/jhotdraw-xml/jhotdraw-xml.iml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jhotdraw.iml b/jhotdraw.iml
new file mode 100644
index 000000000..80df12701
--- /dev/null
+++ b/jhotdraw.iml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/settings.xml b/settings.xml
new file mode 100644
index 000000000..de30eb164
--- /dev/null
+++ b/settings.xml
@@ -0,0 +1,34 @@
+
+
+
+ github
+
+
+
+
+ github
+
+
+ central
+ https://repo1.maven.org/maven2
+
+
+ github
+ GitHub external Packages
+ https://maven.pkg.github.com/sweat-tek/MavenRepository
+
+
+
+
+
+
+
+ github
+ ${env.USER_NAME}
+ ${env.ACCESS_TOKEN}
+
+
+
\ No newline at end of file