diff --git a/jhotdraw-actions/pom.xml b/jhotdraw-actions/pom.xml
index 5cc33e1c6..4e31ac814 100644
--- a/jhotdraw-actions/pom.xml
+++ b/jhotdraw-actions/pom.xml
@@ -24,5 +24,24 @@
jhotdraw-datatransfer
${project.version}
+
+ org.junit.jupiter
+ junit-jupiter
+ RELEASE
+ test
+
+
+ org.mockito
+ mockito-junit-jupiter
+ 4.5.1
+ test
+
+
+ org.mockito
+ mockito-core
+ 4.5.1
+ test
+
+
\ 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..d7853d3a3 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
@@ -56,18 +56,25 @@ public CopyAction(JComponent target) {
@Override
public void actionPerformed(ActionEvent evt) {
- JComponent c = target;
- if (c == null && (KeyboardFocusManager.getCurrentKeyboardFocusManager().
- getPermanentFocusOwner() instanceof JComponent)) {
- c = (JComponent) KeyboardFocusManager.getCurrentKeyboardFocusManager().
- getPermanentFocusOwner();
+ JComponent component = getTargetComponent();
+ if (component != null) {
+ copyToClipboard(component);
}
- // Note: copying is allowed for disabled components
- if (c != null) {
- c.getTransferHandler().exportToClipboard(
- c,
- ClipboardUtil.getClipboard(),
- TransferHandler.COPY);
+ }
+
+ private JComponent getTargetComponent() {
+ if (target != null) {
+ return target;
}
+ Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner();
+ return (focusOwner instanceof JComponent) ? (JComponent) focusOwner : null;
+ }
+
+ private void copyToClipboard(JComponent component) {
+ component.getTransferHandler().exportToClipboard(
+ component,
+ ClipboardUtil.getClipboard(),
+ TransferHandler.COPY
+ );
}
}
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..5ebb4d136 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
@@ -1,17 +1,10 @@
-/*
- * @(#)CutAction.java
- *
- * Copyright (c) 1996-2010 The authors and contributors of JHotDraw.
- * You may not use, copy or modify this file, except in compliance with the
- * accompanying license terms.
- */
package org.jhotdraw.action.edit;
import java.awt.*;
-import java.awt.event.*;
+import java.awt.event.ActionEvent;
import javax.swing.*;
import org.jhotdraw.datatransfer.ClipboardUtil;
-import org.jhotdraw.util.*;
+import org.jhotdraw.util.ResourceBundleUtil;
/**
* Cuts the selected region and places its contents into the system clipboard.
@@ -26,9 +19,7 @@
* If you want this behavior in your application, you have to create an action
* with this ID and put it in your {@code ApplicationModel} in method
* {@link org.jhotdraw.app.ApplicationModel#initApplication}.
- *
- * @author Werner Randelshofer
- * @version $Id$
+ *
*/
public class CutAction extends AbstractSelectionAction {
@@ -50,23 +41,56 @@ public CutAction() {
*/
public CutAction(JComponent target) {
super(target);
+ initializeAction();
+ }
+
+ private void initializeAction() {
ResourceBundleUtil labels = ResourceBundleUtil.getBundle("org.jhotdraw.action.Labels");
labels.configureAction(this, ID);
}
@Override
public void actionPerformed(ActionEvent evt) {
- JComponent c = target;
- if (c == null && (KeyboardFocusManager.getCurrentKeyboardFocusManager().
- getPermanentFocusOwner() instanceof JComponent)) {
- c = (JComponent) KeyboardFocusManager.getCurrentKeyboardFocusManager().
- getPermanentFocusOwner();
+ JComponent component = getActiveComponent();
+ if (isComponentEligibleForCut(component)) {
+ performCutToClipboard(component);
}
- if (c != null && c.isEnabled()) {
- c.getTransferHandler().exportToClipboard(
- c,
- ClipboardUtil.getClipboard(),
- TransferHandler.MOVE);
+ }
+
+ /**
+ * Retrieves the target component, defaulting to the currently focused component if target is null.
+ *
+ * @return the active JComponent or null if none is focused.
+ */
+ private JComponent getActiveComponent() {
+ if (target != null) {
+ return target;
}
+ Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner();
+ return (focusOwner instanceof JComponent) ? (JComponent) focusOwner : null;
+ }
+
+ /**
+ * Checks if the component is eligible for a cut operation.
+ *
+ * @param component the component to check
+ * @return true if component is not null and is enabled
+ */
+ private boolean isComponentEligibleForCut(JComponent component) {
+ return component != null && component.isEnabled();
+ }
+
+ /**
+ * Cuts the contents of the component to the system clipboard.
+ *
+ * @param component the component whose contents are to be cut
+ */
+ private void performCutToClipboard(JComponent component) {
+ component.getTransferHandler().exportToClipboard(
+ component,
+ ClipboardUtil.getClipboard(),
+ TransferHandler.MOVE
+ );
}
}
+
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..79f9df527 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
@@ -77,7 +77,7 @@ public DeleteAction() {
* Creates a new instance which acts on the specified component.
*
* @param target The target of the action. Specify null for the currently
- * focused component.
+ * focused component.
*/
public DeleteAction(JComponent target) {
this(target, ID);
@@ -87,7 +87,7 @@ public DeleteAction(JComponent target) {
* Creates a new instance which acts on the specified component.
*
* @param target The target of the action. Specify null for the currently
- * focused component.
+ * focused component.
*/
protected DeleteAction(JComponent target, String id) {
super(id);
@@ -110,15 +110,15 @@ public void propertyChange(PropertyChangeEvent evt) {
@Override
public void actionPerformed(ActionEvent evt) {
- JComponent c = target;
- if (c == null && (KeyboardFocusManager.getCurrentKeyboardFocusManager().
+ JComponent component = target;
+ if (component == null && (KeyboardFocusManager.getCurrentKeyboardFocusManager().
getPermanentFocusOwner() instanceof JComponent)) {
- c = (JComponent) KeyboardFocusManager.getCurrentKeyboardFocusManager().
+ component = (JComponent) KeyboardFocusManager.getCurrentKeyboardFocusManager().
getPermanentFocusOwner();
}
- if (c != null && c.isEnabled()) {
- if (c instanceof EditableComponent) {
- ((EditableComponent) c).delete();
+ if (component != null && component.isEnabled()) {
+ if (component instanceof EditableComponent) {
+ ((EditableComponent) component).delete();
} else {
deleteNextChar(evt);
}
@@ -130,27 +130,51 @@ public void actionPerformed(ActionEvent evt) {
* DefaultEditorKit.DeleteNextCharAction.actionPerformed(ActionEvent).
*/
public void deleteNextChar(ActionEvent e) {
- JTextComponent c = getTextComponent(e);
- boolean beep = true;
- if ((c != null) && (c.isEditable())) {
- try {
- javax.swing.text.Document doc = c.getDocument();
- Caret caret = c.getCaret();
- int dot = caret.getDot();
- int mark = caret.getMark();
- if (dot != mark) {
- doc.remove(Math.min(dot, mark), Math.abs(dot - mark));
- beep = false;
- } else if (dot < doc.getLength()) {
- doc.remove(dot, 1);
- beep = false;
- }
- } catch (BadLocationException bl) {
- // allowed empty
- }
+ JTextComponent textComponent = getTextComponent(e);
+
+ if (shouldBeepInsteadOfDelete(textComponent)) {
+ Toolkit.getDefaultToolkit().beep();
+ return;
+ }
+
+ try {
+ deleteTextOrNextCharacter(textComponent);
+ } catch (BadLocationException ignored) {
+ // Exception ignored as it's unlikely to occur in practice
}
- if (beep) {
+ }
+// Refactored helper methods
+ private boolean shouldBeepInsteadOfDelete(JTextComponent textComponent) {
+ return textComponent == null || !textComponent.isEditable();
+ }
+
+ private void deleteTextOrNextCharacter(JTextComponent textComponent) throws BadLocationException {
+ Document doc = textComponent.getDocument();
+ Caret caret = textComponent.getCaret();
+
+ if (hasSelection(caret)) {
+ deleteSelectedText(doc, caret);
+ } else if (canDeleteNextCharacter(caret, doc)) {
+ deleteNextCharacter(doc, caret.getDot());
+ } else {
Toolkit.getDefaultToolkit().beep();
}
}
-}
+
+ private boolean hasSelection(Caret caret) {
+ return caret.getDot() != caret.getMark();
+ }
+
+ private void deleteSelectedText(Document doc, Caret caret) throws BadLocationException {
+ int dot = caret.getDot();
+ int mark = caret.getMark();
+ doc.remove(Math.min(dot, mark), Math.abs(dot - mark));
+ }
+
+ private boolean canDeleteNextCharacter(Caret caret, Document doc) {
+ return caret.getDot() < doc.getLength();
+ }
+
+ private void deleteNextCharacter(Document doc, int dot) throws BadLocationException {
+ doc.remove(dot, 1);
+ }}
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..9b3d7f369 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
@@ -13,6 +13,7 @@
import org.jhotdraw.api.gui.EditableComponent;
import org.jhotdraw.util.*;
+
/**
* Duplicates the selected region.
*
@@ -61,7 +62,7 @@ public DuplicateAction() {
* Creates a new instance which acts on the specified component.
*
* @param target The target of the action. Specify null for the currently
- * focused component.
+ * focused component.
*/
public DuplicateAction(JComponent target) {
super(target);
@@ -69,20 +70,37 @@ public DuplicateAction(JComponent target) {
labels.configureAction(this, ID);
}
+
@Override
public void actionPerformed(ActionEvent evt) {
- JComponent c = target;
- if (c == null && (KeyboardFocusManager.getCurrentKeyboardFocusManager().
- getPermanentFocusOwner() instanceof JComponent)) {
- c = (JComponent) KeyboardFocusManager.getCurrentKeyboardFocusManager().
- getPermanentFocusOwner();
+ // Change Variable name
+ JComponent targetComponent = getTargetComponent();
+
+ // Return early if there is no valid or enabled component
+ if (targetComponent == null || !targetComponent.isEnabled()) {
+ return;
}
- if (c != null && c.isEnabled()) {
- if (c instanceof EditableComponent) {
- ((EditableComponent) c).duplicate();
- } else {
- c.getToolkit().beep();
- }
+
+ // Perform duplication if the component is editable
+ if (targetComponent instanceof EditableComponent) {
+ ((EditableComponent) targetComponent).duplicate();
+ } else {
+ targetComponent.getToolkit().beep();
}
}
+ private JComponent getTargetComponent() {
+ // Check if 'target' is available
+ if (target != null) {
+ return target;
+ }
+
+ // Get the component that is currently in focus
+ Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner();
+ if (focusOwner instanceof JComponent) {
+ return (JComponent) focusOwner;
+ }
+
+ // Returnér null, if no valid component is found
+ return null;
+ }
}
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..0fc3ea4ac 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
@@ -26,7 +26,7 @@
*
* If you want this behavior in your application, you have to create an action
* with this ID and put it in your {@code ApplicationModel} in method
- * {@link org.jhotdraw.app.ApplicationModel#initApplication}.
+ * .
*
* @author Werner Randelshofer
* @version $Id$
@@ -56,27 +56,38 @@ public PasteAction(JComponent target) {
}
@Override
- public void actionPerformed(ActionEvent evt) {
- JComponent c = target;
- if (c == null && (KeyboardFocusManager.getCurrentKeyboardFocusManager().
- getPermanentFocusOwner() instanceof JComponent)) {
- c = (JComponent) KeyboardFocusManager.getCurrentKeyboardFocusManager().
- getPermanentFocusOwner();
+ protected void updateEnabled() {
+ if (target != null) {
+ setEnabled(target.isEnabled());
}
- if (c != null && c.isEnabled()) {
- Transferable t = ClipboardUtil.getClipboard().getContents(c);
- if (t != null && c.getTransferHandler() != null) {
- c.getTransferHandler().importData(
- c,
- t);
+ }
+ @Override
+ public void actionPerformed(ActionEvent evt) {
+ JComponent focusedComponent = getTargetComponent();
+
+ if (isComponentEligibleForTransfer(focusedComponent)) {
+ Transferable clipboardContent = ClipboardUtil.getClipboard().getContents(focusedComponent);
+ if (clipboardContent != null) {
+ importDataToComponent(focusedComponent, clipboardContent);
}
}
}
-
- @Override
- protected void updateEnabled() {
+ private JComponent getTargetComponent() {
if (target != null) {
- setEnabled(target.isEnabled());
+ return target;
+ }
+ KeyboardFocusManager focusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+ if (focusManager.getPermanentFocusOwner() instanceof JComponent) {
+ return (JComponent) focusManager.getPermanentFocusOwner();
}
+
+ return null;
+ }
+ private boolean isComponentEligibleForTransfer(JComponent component) {
+ return component != null && component.isEnabled() && component.getTransferHandler() != null;
}
+ private void importDataToComponent(JComponent component, Transferable transferable) {
+ component.getTransferHandler().importData(component, transferable);
+ }
+
}
diff --git a/jhotdraw-actions/src/test/java/org/jhotdraw/action/edit/CopyActionTest.java b/jhotdraw-actions/src/test/java/org/jhotdraw/action/edit/CopyActionTest.java
new file mode 100644
index 000000000..554870a8c
--- /dev/null
+++ b/jhotdraw-actions/src/test/java/org/jhotdraw/action/edit/CopyActionTest.java
@@ -0,0 +1,62 @@
+package org.jhotdraw.action.edit;
+
+import org.jhotdraw.datatransfer.ClipboardUtil;
+import org.junit.jupiter.api.Test;
+
+import javax.swing.*;
+import static org.mockito.Mockito.*;
+import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.awt.*;
+
+import java.awt.event.ActionEvent;
+@ExtendWith(MockitoExtension.class)
+class CopyActionTest {
+ private CopyAction copyAction;
+ @Mock
+ private JComponent targetComponent;
+ @Mock
+ private TransferHandler mockTransferHandler;
+ @Mock
+ private KeyboardFocusManager mockFocusManager;
+
+ @BeforeEach
+ void setUP() {
+ copyAction = new CopyAction(targetComponent);
+ lenient().when(mockFocusManager.getPermanentFocusOwner()).thenReturn(targetComponent);
+ KeyboardFocusManager.setCurrentKeyboardFocusManager(mockFocusManager);
+
+ lenient().when(targetComponent.getTransferHandler()).thenReturn(mockTransferHandler);
+
+ }
+
+ @Test
+ void TestAction() {
+ assertNotNull(targetComponent);
+ }
+
+ @Test
+ void ActionPerformedTest() {
+ ActionEvent event = new ActionEvent(targetComponent, ActionEvent.ACTION_PERFORMED, "copy");
+ // Perform copyAction
+ copyAction.actionPerformed(event);
+
+ verify(mockTransferHandler).exportToClipboard(
+ eq(targetComponent),
+ eq(ClipboardUtil.getClipboard()),
+ eq(TransferHandler.COPY)
+ );
+
+ verify(mockTransferHandler, times(1)).exportToClipboard(
+ eq(targetComponent),
+ eq(ClipboardUtil.getClipboard()),
+ eq(TransferHandler.COPY)
+ );
+
+ }
+}
diff --git a/jhotdraw-core/src/main/java/org/jhotdraw/draw/action/AlignAction.java b/jhotdraw-core/src/main/java/org/jhotdraw/draw/action/AlignAction.java
index 9b682f099..129cab0d9 100644
--- a/jhotdraw-core/src/main/java/org/jhotdraw/draw/action/AlignAction.java
+++ b/jhotdraw-core/src/main/java/org/jhotdraw/draw/action/AlignAction.java
@@ -24,7 +24,6 @@
* @version $Id$
*/
public abstract class AlignAction extends AbstractSelectedAction {
-
private static final long serialVersionUID = 1L;
protected ResourceBundleUtil labels
= ResourceBundleUtil.getBundle("org.jhotdraw.draw.Labels");
diff --git a/jhotdraw-core/src/main/java/org/jhotdraw/draw/figure/Figure.java b/jhotdraw-core/src/main/java/org/jhotdraw/draw/figure/Figure.java
index 2e9b9ab11..7c19de39e 100644
--- a/jhotdraw-core/src/main/java/org/jhotdraw/draw/figure/Figure.java
+++ b/jhotdraw-core/src/main/java/org/jhotdraw/draw/figure/Figure.java
@@ -23,7 +23,10 @@
import org.jhotdraw.draw.tool.Tool;
import org.jhotdraw.geom.Dimension2DDouble;
-/**
+/**public interface Figure {
+ void draw(Graphics2D g); // Hvordan figuren tegnes
+ boolean contains(Point2D p); // Er et punkt inde i figuren?
+ }
* A figure is a graphical element of a {@link Drawing}. A figure
* can be only in one drawing at a time.
*
@@ -601,3 +604,4 @@ public interface Figure extends Cloneable, Serializable {
*/
public void removePropertyChangeListener(PropertyChangeListener listener);
}
+
diff --git a/jhotdraw-gui/src/main/java/org/jhotdraw/color/AbstractColorSlidersModel.java b/jhotdraw-gui/src/main/java/org/jhotdraw/color/AbstractColorSlidersModel.java
index 1359b0019..ee131a275 100644
--- a/jhotdraw-gui/src/main/java/org/jhotdraw/color/AbstractColorSlidersModel.java
+++ b/jhotdraw-gui/src/main/java/org/jhotdraw/color/AbstractColorSlidersModel.java
@@ -19,6 +19,7 @@
*/
public abstract class AbstractColorSlidersModel extends AbstractBean implements ColorSliderModel {
+
private static final long serialVersionUID = 1L;
/**
* ChangeListener's listening to changes in this model.
diff --git a/pom.xml b/pom.xml
index 5f6c7eef5..fc66c4c8e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -71,5 +71,9 @@
jhotdraw-app
jhotdraw-datatransfer
jhotdraw-actions
+
+
+
+
\ No newline at end of file