From 00aae813ded58a7c52de6deaed609bc2a41e3f77 Mon Sep 17 00:00:00 2001
From: eviltester <3K1aDZQQgLtvBXuI>
Date: Sun, 15 Oct 2017 13:10:27 +0100
Subject: [PATCH] amended Robot on counterstring to be cancellable and tidy up
the threading, removed an unused dependency and added an "are you sure" quit
dialog that also quits the counterstring thread
---
README.md | 9 +
pom.xml | 5 +-
.../cannedtext/CannedTextItemTreeFinder.java | 4 +-
.../html/comments/HTMLCommentReporter.java | 4 +-
.../javafortesters/javafx/Config.java | 4 +-
.../javafx/CounterStringStage.java | 232 ++++++++++--------
.../javafortesters/javafx/County.java | 41 ++++
.../javafortesters/javafx/MainGui.java | 37 ++-
.../javafx/StringGeneratorStage.java | 10 +-
.../javafx/UrlLauncherGridStage.java | 3 -
.../launcher/LauncherUrlLoader.java | 3 -
.../launcher/LauncherUrlSet.java | 3 -
.../CounterstringCreationTest.java | 3 -
.../launcher/UrlLauncherTest.java | 4 +-
14 files changed, 227 insertions(+), 135 deletions(-)
create mode 100644 src/main/java/uk/co/compendiumdev/javafortesters/javafx/County.java
diff --git a/README.md b/README.md
index 1e1f5ad..32bf6a2 100644
--- a/README.md
+++ b/README.md
@@ -121,6 +121,15 @@ Compendium_Developments = https://www.compendiumdev.co.uk
## Release Notes
+### 20171015 15th October 2017
+
+- Amended Robot counterstring generator to not have a hanging thread that keeps going
+ - used service for JavaFx
+- click on 'Robot' button during counterstring generation while typing cancels the generation and typing
+- added handlers to prompt for application exit
+- added handlers to stop counterstring service when window hidden or application closes
+- Added - Y/N Exit App dialog
+
### 20161112
- started using this in videos for youtube, so other people saw it
diff --git a/pom.xml b/pom.xml
index c3b342b..d46d7cb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,8 @@
uk.co.compendiumdev
testtoolhub
- 1.1-SNAPSHOT
+
+ 1.1
@@ -15,11 +16,13 @@
junit
4.11
+
org.apache.httpcomponents
diff --git a/src/main/java/uk/co/compendiumdev/javafortesters/cannedtext/CannedTextItemTreeFinder.java b/src/main/java/uk/co/compendiumdev/javafortesters/cannedtext/CannedTextItemTreeFinder.java
index fdd0302..c21512b 100644
--- a/src/main/java/uk/co/compendiumdev/javafortesters/cannedtext/CannedTextItemTreeFinder.java
+++ b/src/main/java/uk/co/compendiumdev/javafortesters/cannedtext/CannedTextItemTreeFinder.java
@@ -2,9 +2,7 @@
import uk.co.compendiumdev.javafortesters.tree.TreeBranch;
-/**
- * Created by Alan on 27/02/2015.
- */
+
public class CannedTextItemTreeFinder {
private final TreeBranch root;
diff --git a/src/main/java/uk/co/compendiumdev/javafortesters/html/comments/HTMLCommentReporter.java b/src/main/java/uk/co/compendiumdev/javafortesters/html/comments/HTMLCommentReporter.java
index c19d112..e42e3f9 100644
--- a/src/main/java/uk/co/compendiumdev/javafortesters/html/comments/HTMLCommentReporter.java
+++ b/src/main/java/uk/co/compendiumdev/javafortesters/html/comments/HTMLCommentReporter.java
@@ -5,9 +5,7 @@
import java.io.IOException;
-/**
- * Created by Alan on 24/03/2015.
- */
+
public class HTMLCommentReporter {
HTMLCommentFinder comments;
diff --git a/src/main/java/uk/co/compendiumdev/javafortesters/javafx/Config.java b/src/main/java/uk/co/compendiumdev/javafortesters/javafx/Config.java
index a0a43d6..bdfe257 100644
--- a/src/main/java/uk/co/compendiumdev/javafortesters/javafx/Config.java
+++ b/src/main/java/uk/co/compendiumdev/javafortesters/javafx/Config.java
@@ -1,8 +1,6 @@
package uk.co.compendiumdev.javafortesters.javafx;
-/**
- * Created by Alan on 21/01/2015.
- */
+
public class Config {
public static int getDefaultWindowWidth(){
diff --git a/src/main/java/uk/co/compendiumdev/javafortesters/javafx/CounterStringStage.java b/src/main/java/uk/co/compendiumdev/javafortesters/javafx/CounterStringStage.java
index 1182f0a..d8ef883 100644
--- a/src/main/java/uk/co/compendiumdev/javafortesters/javafx/CounterStringStage.java
+++ b/src/main/java/uk/co/compendiumdev/javafortesters/javafx/CounterStringStage.java
@@ -1,36 +1,32 @@
package uk.co.compendiumdev.javafortesters.javafx;
-import uk.co.compendiumdev.javafortesters.counterstrings.CounterString;
-import uk.co.compendiumdev.javafortesters.counterstrings.CounterStringCreationError;
-import uk.co.compendiumdev.javafortesters.counterstrings.CounterStringRangeListIterator;
-import uk.co.compendiumdev.javafortesters.counterstrings.CounterStringRangeStruct;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
+import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
+import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.*;
-import javafx.scene.control.Button;
-import javafx.scene.control.Label;
-import javafx.scene.control.TextArea;
-import javafx.scene.control.TextField;
import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
import javafx.scene.layout.*;
import javafx.stage.Stage;
+import javafx.stage.WindowEvent;
+import uk.co.compendiumdev.javafortesters.counterstrings.CounterString;
+import uk.co.compendiumdev.javafortesters.counterstrings.CounterStringCreationError;
-import java.awt.*;
import java.awt.event.KeyEvent;
import java.io.PrintWriter;
import java.io.StringWriter;
-import java.util.List;
public class CounterStringStage extends Stage {
private static CounterStringStage counterStringSingletonStage=null;
+ private static Service task;
public static void singletonActivate(){
@@ -41,38 +37,7 @@ public static void singletonActivate(){
counterStringSingletonStage.requestFocus();
}
- private class County{
-
- private List range;
- private CounterStringRangeListIterator ranger;
- private CounterString counterstring;
- private String spacer;
- private Robot robot;
-
- public void createCounterStringRangesFor(int counterStringLength, String spacer) {
- this.counterstring = new CounterString();
- this.spacer = counterstring.getSingleCharSpacer(spacer);
- this.range = counterstring.createCounterStringRangesFor(counterStringLength, spacer);
- this.ranger = new CounterStringRangeListIterator(range);
- try {
- this.robot = new Robot();
- } catch (AWTException e) {
- e.printStackTrace();
- }
- }
-
- public boolean hasAnotherValueInRangeList() {
- return this.ranger.hasAnotherValueInRangeList();
- }
-
- public String getNextCounterStringEntry() {
- return counterstring.getCounterStringRepresentationOfNumber(ranger.getNextCounterStringValue(), this.spacer);
- }
- public Robot getRobot(){
- return this.robot;
- }
- }
public CounterStringStage(boolean hidden) {
@@ -141,103 +106,154 @@ public CounterStringStage(boolean hidden) {
if(!hidden)
this.show();
+
+
+ // when close stage, stop the counterstring generation
+ this.addEventHandler(WindowEvent.WINDOW_CLOSE_REQUEST, new EventHandler() {
+ @Override
+ public void handle(Event event) {
+ if(task!=null) {
+ if (task.isRunning()) {
+ task.cancel();
+ robotType.setText("Robot");
+ robotType.setTooltip(new Tooltip("Have robot type counterstring into field"));
+ }
+ }
+ }
+ });
+
+ // when focus changes stop the counterstring generation
+// this.focusedProperty().addListener(new ChangeListener() {
+// @Override
+// public void changed(ObservableValue extends Boolean> observable, Boolean oldValue, Boolean newValue) {
+// if(task!=null) {
+// if (task.isRunning()) {
+// task.cancel();
+// robotType.setText("Robot");
+// robotType.setTooltip(new Tooltip("Have robot type counterstring into field"));
+// }
+// }
+// }
+// });
+
+
County county = new County();
//robot typing into field- never stop thread - once robot is used a thread ticks over in the background
// ready to be re-used
- Task task = new Task() {
+ task = new Service() {
@Override
- public Void call() throws Exception {
- int x=5;
- while(true) {
- if(robotType.getText().startsWith("Robot")){
- x=5;
- }
- final int finalX = x--;
+ protected Task createTask() {
+ return new Task(){
+ @Override
+ public Void call() throws Exception {
+ int x=5;
- Platform.runLater(new Runnable() {
- @Override
- public void run() {
+ while(!isCancelled()) {
+ if(robotType.getText().startsWith("Robot")){
+ x=5;
+ }
+ final int finalX = x--;
+ Platform.runLater(new Runnable() {
+ @Override
+ public void run() {
- // This needs to be a state machine
- // Robot means stop don't do anything
- // Start means start counting down
- // In [ means continue counting
- // GO means calculate the counterstring
- // ... means iterate through and send the keys
- if (robotType.getText().startsWith("Start") || robotType.getText().startsWith("In [")) {
- robotType.setText("In [" + finalX + "] secs");
- }
- if (finalX <= 0) {
- robotType.setText("GO");
- // calculate counterstring and iterator here
- robotType.setText("...");
- }
- if(robotType.getText().startsWith("...")){
- if(county.hasAnotherValueInRangeList()){
- String outputString = county.getNextCounterStringEntry();
- robotType.setText("..."+outputString);
- //System.out.println(outputString);
- for(char c : outputString.toCharArray()) {
- //System.out.println(""+c);
- // this hack means that with robot we should really default to *
- if(c=='*'){
- county.getRobot().keyPress(KeyEvent.VK_SHIFT);
- county.getRobot().keyPress(KeyEvent.VK_8);
- county.getRobot().keyRelease(KeyEvent.VK_8);
- county.getRobot().keyRelease(KeyEvent.VK_SHIFT);
- }else {
- county.getRobot().keyPress(KeyEvent.getExtendedKeyCodeForChar(c));
- county.getRobot().keyRelease(KeyEvent.getExtendedKeyCodeForChar(c));
+ // This needs to be a state machine
+ // Robot means stop don't do anything
+ // Start means start counting down
+ // In [ means continue counting
+ // GO means calculate the counterstring
+ // ... means iterate through and send the keys
+ if (robotType.getText().startsWith("Start") || robotType.getText().startsWith("In [")) {
+ robotType.setText("In [" + finalX + "] secs");
+ }
+ if (finalX <= 0) {
+ robotType.setText("GO");
+ // calculate counterstring and iterator here
+
+ robotType.setText("...");
+ }
+ if(robotType.getText().startsWith("...")){
+ if(county.hasAnotherValueInRangeList()){
+ String outputString = county.getNextCounterStringEntry();
+ robotType.setText("..."+outputString);
+ //System.out.println(outputString);
+ for(char c : outputString.toCharArray()) {
+ //System.out.println(""+c);
+ // this hack means that with robot we should really default to *
+ if(c=='*'){
+ county.getRobot().keyPress(KeyEvent.VK_SHIFT);
+ county.getRobot().keyPress(KeyEvent.VK_8);
+ county.getRobot().keyRelease(KeyEvent.VK_8);
+ county.getRobot().keyRelease(KeyEvent.VK_SHIFT);
+ }else {
+ county.getRobot().keyPress(KeyEvent.getExtendedKeyCodeForChar(c));
+ county.getRobot().keyRelease(KeyEvent.getExtendedKeyCodeForChar(c));
+ }
+ if(isCancelled()){
+ break;
+ }
+ }
+ }else{
+ // we are finished
+ robotType.setText("Robot");
+ robotType.setTooltip(new Tooltip("Have robot type counterstring into field"));
+ cancel();
+ return;
}
}
- }else{
- // we are finished
- robotType.setText("Robot");
}
+ });
+
+ if(robotType.getText().startsWith("Robot")||robotType.getText().startsWith("In [")) {
+ Thread.sleep(1000);
+ }else{
+ Thread.sleep(10);
+ x=5;
}
+ System.out.println("Thread " + x);
}
- });
-
- if(robotType.getText().startsWith("Robot")||robotType.getText().startsWith("In [")) {
- Thread.sleep(1000);
- }else{
- Thread.sleep(10);
- x=5;
+ return null;
}
- System.out.println("Thread " + x);
- }
+ };
}
};
- Thread th = new Thread(task);
- th.setDaemon(true);
-
-
-
robotType.setOnAction(
new EventHandler() {
+
@Override
public void handle(ActionEvent e) {
+
System.out.println("clicked robot");
try {
- if(!th.isAlive()) {
- th.start();
+ if(task.isRunning()){
+ robotType.setText("Cancelling");
+ task.cancel();
+ robotType.setText("Robot");
+ robotType.setTooltip(new Tooltip("Have robot type counterstring into field"));
+ return;
}
+
if(robotType.getText().startsWith("Robot")){
- county.createCounterStringRangesFor(Integer.parseInt(counterLength.getText()), counterstringSpacer.getText());
- robotType.setText("Start");
+ if(!task.isRunning()){
+ task.reset();
+ county.createCounterStringRangesFor(Integer.parseInt(counterLength.getText()), counterstringSpacer.getText());
+ robotType.setText("Start");
+ robotType.setTooltip(new Tooltip("Click Button again to cancel Robot Typing"));
+ task.start();
+ }
}else{
robotType.setText("Robot");
@@ -335,6 +351,7 @@ public void handle(ActionEvent e) {
});
+
}
@@ -406,4 +423,13 @@ private void sendToClipboard(String contents, Button copyCounter) {
}
+ public static void stopServices() {
+ if(task!=null){
+ if(task.isRunning()){
+ task.cancel();
+ task=null;
+ }
+ }
+
+ }
}
diff --git a/src/main/java/uk/co/compendiumdev/javafortesters/javafx/County.java b/src/main/java/uk/co/compendiumdev/javafortesters/javafx/County.java
new file mode 100644
index 0000000..3c3de4a
--- /dev/null
+++ b/src/main/java/uk/co/compendiumdev/javafortesters/javafx/County.java
@@ -0,0 +1,41 @@
+package uk.co.compendiumdev.javafortesters.javafx;
+
+import uk.co.compendiumdev.javafortesters.counterstrings.CounterString;
+import uk.co.compendiumdev.javafortesters.counterstrings.CounterStringRangeListIterator;
+import uk.co.compendiumdev.javafortesters.counterstrings.CounterStringRangeStruct;
+
+import java.awt.*;
+import java.util.List;
+
+public class County {
+
+ private List range;
+ private CounterStringRangeListIterator ranger;
+ private CounterString counterstring;
+ private String spacer;
+ private Robot robot;
+
+ public void createCounterStringRangesFor(int counterStringLength, String spacer) {
+ this.counterstring = new CounterString();
+ this.spacer = counterstring.getSingleCharSpacer(spacer);
+ this.range = counterstring.createCounterStringRangesFor(counterStringLength, spacer);
+ this.ranger = new CounterStringRangeListIterator(range);
+ try {
+ this.robot = new Robot();
+ } catch (AWTException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public boolean hasAnotherValueInRangeList() {
+ return this.ranger.hasAnotherValueInRangeList();
+ }
+
+ public String getNextCounterStringEntry() {
+ return counterstring.getCounterStringRepresentationOfNumber(ranger.getNextCounterStringValue(), this.spacer);
+ }
+
+ public Robot getRobot(){
+ return this.robot;
+ }
+}
diff --git a/src/main/java/uk/co/compendiumdev/javafortesters/javafx/MainGui.java b/src/main/java/uk/co/compendiumdev/javafortesters/javafx/MainGui.java
index 0709231..9df15f0 100644
--- a/src/main/java/uk/co/compendiumdev/javafortesters/javafx/MainGui.java
+++ b/src/main/java/uk/co/compendiumdev/javafortesters/javafx/MainGui.java
@@ -1,20 +1,24 @@
package uk.co.compendiumdev.javafortesters.javafx;
import javafx.application.Application;
+import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
+import javafx.scene.control.Alert;
import javafx.scene.control.Button;
+import javafx.scene.control.ButtonType;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
+import javafx.stage.WindowEvent;
public class MainGui extends Application{
- //TODO: Prompt "Are you sure?" when closing main form, then exit app if YES
+ //DONE: Prompt "Are you sure?" when closing main form, then exit app if YES
//TODO: Repeat strings
//DONE: counterstring generator
//TODO: string generator to file
@@ -79,6 +83,10 @@ public void start(Stage stage) {
BorderPane root = new BorderPane();
Scene scene = new Scene(root, 400, 100);
+
+ stage.setOnCloseRequest(exitApplicationHandler());
+
+
VBox buttonList = new VBox(10);
HBox buttonsRow1 = new HBox();
@@ -177,6 +185,33 @@ public void handle(ActionEvent e) {
});
}
+ private EventHandler exitApplicationHandler() {
+ return new EventHandler() {
+ @Override
+ public void handle(WindowEvent event) {
+
+ Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
+ alert.setTitle("Confirm Application Exit");
+ alert.setHeaderText("Are you sure you want to quit the application?");
+ alert.setContentText("Press OK to exit the application. Press Cancel to exit this dialog and keep the application running.");
+ alert.showAndWait().ifPresent(rs -> {
+ if (rs == ButtonType.OK) {
+
+
+ CounterStringStage.stopServices();
+ Platform.exit();
+ System.exit(0);
+ }else{
+ event.consume();
+ }
+ });
+
+
+ }
+ };
+
+ }
+
public static void main(String[] args) {
launch(args);
}
diff --git a/src/main/java/uk/co/compendiumdev/javafortesters/javafx/StringGeneratorStage.java b/src/main/java/uk/co/compendiumdev/javafortesters/javafx/StringGeneratorStage.java
index a1810d4..3e90bce 100644
--- a/src/main/java/uk/co/compendiumdev/javafortesters/javafx/StringGeneratorStage.java
+++ b/src/main/java/uk/co/compendiumdev/javafortesters/javafx/StringGeneratorStage.java
@@ -23,9 +23,6 @@
public class StringGeneratorStage extends Stage {
-
- // TODO Warning STring generator can cause display errors, often best to go direct to clipboard
-
private static StringGeneratorStage stringGeneratorSingletonStage=null;
public static void singletonActivate() {
@@ -59,7 +56,7 @@ public StringGeneratorStage(boolean hidden){
HBox asciiControlCharToCharInputs = new HBox();
final Label firstCharLbl = new Label("First Value:");
final TextField firstCharTxt = new TextField ();
- firstCharTxt.setText("0");
+ firstCharTxt.setText("1");
final Label secondCharLbl = new Label("Second Value:");
final TextField secondCharTxt = new TextField ();
secondCharTxt.setText("255");
@@ -92,7 +89,7 @@ public StringGeneratorStage(boolean hidden){
asciiControlCharToCharInputs.setSpacing(10);
asciiControlCharToCharButtons.setSpacing(10);
- final Label warning = new Label("Warning: unicode values can cause rendering issues in this control");
+ final Label warning = new Label("Warning: unicode values can cause rendering issues in this control, and '0' will not render to clipboard");
final Button clearTextArea = new Button();
clearTextArea.setText("Clear");
@@ -131,7 +128,7 @@ public void handle(ActionEvent e) {
}
}
});
-
+
copyToClipboard.setOnAction(
new EventHandler() {
@Override
@@ -279,6 +276,7 @@ private void alertFirstOrSecondCharNotNumeric() {
private void sendToClipboard(String contents, Button copyCounter) {
copyCounter.setText("Copying");
Clipboard clipboard = Clipboard.getSystemClipboard();
+ clipboard.clear();
ClipboardContent content = new ClipboardContent();
content.putString(contents);
clipboard.setContent(content);
diff --git a/src/main/java/uk/co/compendiumdev/javafortesters/javafx/UrlLauncherGridStage.java b/src/main/java/uk/co/compendiumdev/javafortesters/javafx/UrlLauncherGridStage.java
index 032ca78..9822ec4 100644
--- a/src/main/java/uk/co/compendiumdev/javafortesters/javafx/UrlLauncherGridStage.java
+++ b/src/main/java/uk/co/compendiumdev/javafortesters/javafx/UrlLauncherGridStage.java
@@ -21,9 +21,6 @@
import javafx.util.Callback;
-/**
- * Created by alan on 12/03/15.
- */
public class UrlLauncherGridStage extends Stage {
private static UrlLauncherGridStage urlLauncherGridSingletonStage=null;
diff --git a/src/main/java/uk/co/compendiumdev/javafortesters/launcher/LauncherUrlLoader.java b/src/main/java/uk/co/compendiumdev/javafortesters/launcher/LauncherUrlLoader.java
index 8afbd6b..8a78d0f 100644
--- a/src/main/java/uk/co/compendiumdev/javafortesters/launcher/LauncherUrlLoader.java
+++ b/src/main/java/uk/co/compendiumdev/javafortesters/launcher/LauncherUrlLoader.java
@@ -6,9 +6,6 @@
import java.util.Map;
import java.util.Properties;
-/**
- * Created by alan on 10/03/15.
- */
public class LauncherUrlLoader {
public UrlLauncher load() {
diff --git a/src/main/java/uk/co/compendiumdev/javafortesters/launcher/LauncherUrlSet.java b/src/main/java/uk/co/compendiumdev/javafortesters/launcher/LauncherUrlSet.java
index 7ae933d..aad7c45 100644
--- a/src/main/java/uk/co/compendiumdev/javafortesters/launcher/LauncherUrlSet.java
+++ b/src/main/java/uk/co/compendiumdev/javafortesters/launcher/LauncherUrlSet.java
@@ -4,9 +4,6 @@
import java.util.HashMap;
import java.util.Map;
-/**
- * Created by alan on 10/03/15.
- */
public class LauncherUrlSet {
private static final int DEFAULT_MILLIS = 1000;
private static final int DEFAULT_RETRIES = 3;
diff --git a/src/test/java/uk/co/compendiumdev/javafortesters/counterstrings/CounterstringCreationTest.java b/src/test/java/uk/co/compendiumdev/javafortesters/counterstrings/CounterstringCreationTest.java
index fcf8f69..6ffb427 100644
--- a/src/test/java/uk/co/compendiumdev/javafortesters/counterstrings/CounterstringCreationTest.java
+++ b/src/test/java/uk/co/compendiumdev/javafortesters/counterstrings/CounterstringCreationTest.java
@@ -4,9 +4,6 @@
import org.junit.Ignore;
import org.junit.Test;
-/**
- * Created by alan on 08/12/2014.
- */
public class CounterstringCreationTest {
@Test
diff --git a/src/test/java/uk/co/compendiumdev/javafortesters/launcher/UrlLauncherTest.java b/src/test/java/uk/co/compendiumdev/javafortesters/launcher/UrlLauncherTest.java
index 240e5dc..231635e 100644
--- a/src/test/java/uk/co/compendiumdev/javafortesters/launcher/UrlLauncherTest.java
+++ b/src/test/java/uk/co/compendiumdev/javafortesters/launcher/UrlLauncherTest.java
@@ -8,9 +8,7 @@
import java.util.*;
import java.util.List;
-/**
- * Created by alan on 09/03/15.
- */
+
public class UrlLauncherTest {
// Todo, need assertions and mocks etc. in these tests as url launching not tested by this