Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .github/workflows/maven.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Java CI with Maven

on:
push:
branches: [ feature/arrange-send-to-front-or-back ]

pull_request:
branches: [ develop ]


jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: read

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: maven

- name: Build with Maven
run: mvn -B -DskipTests package -s .maven-settings.xml
env:
GITHUB_ACTOR: ${{ github.actor }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Run tests
run: mvn -B test -s .maven-settings.xml
env:
GITHUB_ACTOR: ${{ github.actor }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
11 changes: 11 additions & 0 deletions .maven-settings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
<server>
<id>github</id>
<username>${env.GITHUB_ACTOR}</username>
<password>${env.GITHUB_TOKEN}</password>
</server>
</servers>
</settings>
20 changes: 19 additions & 1 deletion jhotdraw-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,28 @@
<version>6.8.21</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.tngtech.jgiven</groupId>
<artifactId>jgiven-junit</artifactId>
<version>1.3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.26.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jhotdraw-actions</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* @(#)AbstractZOrderAction.java
*
* Copyright (c) 2003-2008 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.draw.action;

import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import javax.swing.undo.AbstractUndoableEdit;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
import org.jhotdraw.draw.Drawing;
import org.jhotdraw.draw.DrawingEditor;
import org.jhotdraw.draw.DrawingView;
import org.jhotdraw.draw.figure.Figure;
import org.jhotdraw.util.ResourceBundleUtil;

/**
* Defines the common workflow for z-order actions on selected figures.
*/
public abstract class AbstractZOrderAction extends AbstractSelectedAction {

private static final long serialVersionUID = 1L;
private final String id;

protected AbstractZOrderAction(DrawingEditor editor, String id) {
super(editor);
this.id = id;
ResourceBundleUtil labels
= ResourceBundleUtil.getBundle("org.jhotdraw.draw.Labels");
labels.configureAction(this, id);
updateEnabledState();
}

@Override
public void actionPerformed(ActionEvent e) {
final DrawingView view = Objects.requireNonNull(
getView(),
"A z-order action requires an active drawing view.");
final Drawing drawing = Objects.requireNonNull(
view.getDrawing(),
"A z-order action requires an attached drawing.");
final LinkedList<Figure> figures = new LinkedList<>(view.getSelectedFigures());
assert figures != null : "Selected figures collection must not be null.";
final List<Figure> originalOrder = new ArrayList<>(drawing.getChildren());
reorder(view, figures);
final List<Figure> reorderedOrder = new ArrayList<>(drawing.getChildren());
fireUndoableEditHappened(new AbstractUndoableEdit() {
private static final long serialVersionUID = 1L;

@Override
public String getPresentationName() {
ResourceBundleUtil labels
= ResourceBundleUtil.getBundle("org.jhotdraw.draw.Labels");
return labels.getTextProperty(id);
}

@Override
public void redo() throws CannotRedoException {
super.redo();
restoreOrder(drawing, reorderedOrder);
}

@Override
public void undo() throws CannotUndoException {
super.undo();
restoreOrder(drawing, originalOrder);
}
});
}

private void restoreOrder(Drawing drawing, List<Figure> order) {
drawing.basicRemoveAll(new ArrayList<>(drawing.getChildren()));
drawing.basicAddAll(0, order);
}

protected abstract void reorder(DrawingView view, Collection<Figure> figures);

protected abstract void reverseReorder(DrawingView view, Collection<Figure> figures);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,15 @@

import org.jhotdraw.draw.figure.Figure;
import java.util.*;
import javax.swing.undo.*;
import org.jhotdraw.draw.*;
import org.jhotdraw.util.ResourceBundleUtil;

/**
* ToFrontAction.
*
* @author Werner Randelshofer
* @version $Id$
*/
public class BringToFrontAction extends AbstractSelectedAction {
public class BringToFrontAction extends AbstractZOrderAction {

private static final long serialVersionUID = 1L;
public static final String ID = "edit.bringToFront";
Expand All @@ -28,44 +26,25 @@ public class BringToFrontAction extends AbstractSelectedAction {
* Creates a new instance.
*/
public BringToFrontAction(DrawingEditor editor) {
super(editor);
ResourceBundleUtil labels
= ResourceBundleUtil.getBundle("org.jhotdraw.draw.Labels");
labels.configureAction(this, ID);
updateEnabledState();
super(editor, ID);
}

@Override
public void actionPerformed(java.awt.event.ActionEvent e) {
final DrawingView view = getView();
final LinkedList<Figure> figures = new LinkedList<>(view.getSelectedFigures());
protected void reorder(DrawingView view, Collection<Figure> figures) {
bringToFront(view, figures);
fireUndoableEditHappened(new AbstractUndoableEdit() {
private static final long serialVersionUID = 1L;

@Override
public String getPresentationName() {
ResourceBundleUtil labels
= ResourceBundleUtil.getBundle("org.jhotdraw.draw.Labels");
return labels.getTextProperty(ID);
}

@Override
public void redo() throws CannotRedoException {
super.redo();
BringToFrontAction.bringToFront(view, figures);
}
}

@Override
public void undo() throws CannotUndoException {
super.undo();
SendToBackAction.sendToBack(view, figures);
}
});
@Override
protected void reverseReorder(DrawingView view, Collection<Figure> figures) {
SendToBackAction.sendToBack(view, figures);
}

public static void bringToFront(DrawingView view, Collection<Figure> figures) {
Drawing drawing = view.getDrawing();
Objects.requireNonNull(view, "DrawingView must not be null.");
Objects.requireNonNull(figures, "Figures collection must not be null.");
Drawing drawing = Objects.requireNonNull(
view.getDrawing(),
"DrawingView must provide a drawing.");
for (Figure figure : drawing.sort(figures)) {
drawing.bringToFront(figure);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,16 @@

import org.jhotdraw.draw.figure.Figure;
import java.util.*;
import javax.swing.undo.*;
import org.jhotdraw.draw.*;
import org.jhotdraw.util.ResourceBundleUtil;
import org.jhotdraw.util.ReversedList;

/**
* SendToBackAction.
*
* @author Werner Randelshofer
* @version $Id$
*/
public class SendToBackAction extends AbstractSelectedAction {
public class SendToBackAction extends AbstractZOrderAction {

private static final long serialVersionUID = 1L;
public static final String ID = "edit.sendToBack";
Expand All @@ -28,45 +27,27 @@ public class SendToBackAction extends AbstractSelectedAction {
* Creates a new instance.
*/
public SendToBackAction(DrawingEditor editor) {
super(editor);
ResourceBundleUtil labels
= ResourceBundleUtil.getBundle("org.jhotdraw.draw.Labels");
labels.configureAction(this, ID);
updateEnabledState();
super(editor, ID);
}

@Override
public void actionPerformed(java.awt.event.ActionEvent e) {
final DrawingView view = getView();
final LinkedList<Figure> figures = new LinkedList<>(view.getSelectedFigures());
protected void reorder(DrawingView view, Collection<Figure> figures) {
sendToBack(view, figures);
fireUndoableEditHappened(new AbstractUndoableEdit() {
private static final long serialVersionUID = 1L;

@Override
public String getPresentationName() {
ResourceBundleUtil labels
= ResourceBundleUtil.getBundle("org.jhotdraw.draw.Labels");
return labels.getTextProperty(ID);
}

@Override
public void redo() throws CannotRedoException {
super.redo();
SendToBackAction.sendToBack(view, figures);
}
}

@Override
public void undo() throws CannotUndoException {
super.undo();
BringToFrontAction.bringToFront(view, figures);
}
});
@Override
protected void reverseReorder(DrawingView view, Collection<Figure> figures) {
BringToFrontAction.bringToFront(view, figures);
}

public static void sendToBack(DrawingView view, Collection<Figure> figures) {
Drawing drawing = view.getDrawing();
for (Figure figure : figures) { // XXX Shouldn't the figures be sorted here back to front?
Objects.requireNonNull(view, "DrawingView must not be null.");
Objects.requireNonNull(figures, "Figures collection must not be null.");
Drawing drawing = Objects.requireNonNull(
view.getDrawing(),
"DrawingView must provide a drawing.");
List<Figure> sorted = drawing.sort(figures);
for (Figure figure : new ReversedList<>(sorted)) {
drawing.sendToBack(figure);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package org.jhotdraw.draw;

import java.awt.geom.Point2D;
import java.util.Arrays;
import java.util.List;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
import javax.swing.undo.UndoableEdit;
import org.jhotdraw.draw.figure.Figure;
import org.jhotdraw.draw.figure.RectangleFigure;
import static org.junit.Assert.assertEquals;

public final class ArrangeTestSupport {

private ArrangeTestSupport() {
}

public static DefaultDrawingView createDefaultView() {
return createView(new DefaultDrawing());
}

public static DefaultDrawingView createQuadTreeView() {
return createView(new QuadTreeDrawing());
}

public static DefaultDrawingView createView(Drawing drawing) {
DefaultDrawingView view = new DefaultDrawingView();
view.setDrawing(drawing);
return view;
}

public static Figure addFigure(DefaultDrawingView view, double x) {
RectangleFigure figure = new RectangleFigure();
figure.setBounds(new Point2D.Double(x, 0), new Point2D.Double(x + 5, 5));
view.getDrawing().add(figure);
return figure;
}

public static void select(DefaultDrawingView view, Figure... figures) {
view.clearSelection();
view.addToSelection(Arrays.asList(figures));
}

public static void assertOrder(DefaultDrawingView view, Figure... expected) {
List<Figure> actual = view.getDrawing().sort(Arrays.asList(expected));
assertEquals(Arrays.asList(expected), actual);
}

public static UndoableEdit captureUndoableEdit(Drawing drawing, Runnable trigger) {
final UndoableEdit[] captured = new UndoableEdit[1];
UndoableEditListener listener = new UndoableEditListener() {
@Override
public void undoableEditHappened(UndoableEditEvent e) {
captured[0] = e.getEdit();
}
};
drawing.addUndoableEditListener(listener);
try {
trigger.run();
} finally {
drawing.removeUndoableEditListener(listener);
}
if (captured[0] == null) {
throw new AssertionError("Expected an undoable edit to be published.");
}
return captured[0];
}
}
Loading