From 9411e0aa5eb9f8dad8649e8aa4f0908ffe4e5e47 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Mon, 30 Jan 2023 13:14:07 -0500 Subject: [PATCH 1/7] Start rewriting GUI Turns out, packaging JavaFXML into a FatJAR is essentially impossible. Ah well, time to do things the old-fashioned way... --- dependency-reduced-pom.xml | 27 +- pom.xml | 14 +- src/main/java/module-info.java | 1 + src/main/java/org/baxter/disco/ocr/Cli.java | 17 +- src/main/java/org/baxter/disco/ocr/Gui.java | 254 +++++++++++++++++- .../java/org/baxter/disco/ocr/GuiStarter.java | 18 ++ .../java/org/baxter/disco/ocr/cameraTest.fxml | 151 ----------- .../java/org/baxter/disco/ocr/logParsing.fxml | 88 ------ .../java/org/baxter/disco/ocr/mainMenu.fxml | 47 ++-- .../org/baxter/disco/ocr/movementTest.fxml | 52 ---- .../cameraCalibration.fxml} | 0 11 files changed, 329 insertions(+), 340 deletions(-) create mode 100644 src/main/java/org/baxter/disco/ocr/GuiStarter.java delete mode 100644 src/main/java/org/baxter/disco/ocr/cameraTest.fxml delete mode 100644 src/main/java/org/baxter/disco/ocr/logParsing.fxml delete mode 100644 src/main/java/org/baxter/disco/ocr/movementTest.fxml rename src/main/{java/org/baxter/disco/ocr/calibrationMenu.fxml => resources/cameraCalibration.fxml} (100%) diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml index 5152179..2090eff 100644 --- a/dependency-reduced-pom.xml +++ b/dependency-reduced-pom.xml @@ -4,7 +4,7 @@ org.baxter.disco ocr Disco OCR Accuracy Over Life Testing - 4.0.0-rc1 + 4.0.0-rc2 Testing Discos for long-term accuracy, using automated optical character recognition. Baxter International @@ -62,7 +62,7 @@ - org.baxter.disco.ocr.Cli + org.baxter.disco.ocr.GuiStarter @@ -84,6 +84,29 @@ + + maven-assembly-plugin + 3.3.0 + + + package + + single + + + + + true + org.baxter.disco.ocr.GuiStarter + + + + jar-with-dependencies + + + + + diff --git a/pom.xml b/pom.xml index b2f6297..91f8250 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.baxter.disco ocr - 4.0.0-rc1 + 4.0.0-rc2 jar Disco OCR Accuracy Over Life Testing Testing Discos for long-term accuracy, using automated optical character recognition. @@ -86,7 +86,7 @@ ${pi4j.version} - + org.openjfx javafx-fxml @@ -155,7 +155,7 @@ - org.baxter.disco.ocr.Cli + org.baxter.disco.ocr.GuiStarter @@ -178,7 +178,7 @@ - + diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index ef88b29..80e8d13 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -4,6 +4,7 @@ module org.baxter.disco.ocr { requires com.pi4j.plugin.pigpio; requires com.pi4j.library.pigpio; requires javafx.fxml; + requires javafx.controls; requires org.apache.poi.poi; requires org.apache.commons.configuration2; requires org.apache.xmlbeans; diff --git a/src/main/java/org/baxter/disco/ocr/Cli.java b/src/main/java/org/baxter/disco/ocr/Cli.java index 610909b..47a3825 100644 --- a/src/main/java/org/baxter/disco/ocr/Cli.java +++ b/src/main/java/org/baxter/disco/ocr/Cli.java @@ -96,11 +96,7 @@ public class Cli } finally { - ErrorLogging.logError("DEBUG: PROGRAM CLOSING."); - inputScanner.close(); - MovementFacade.closeGPIO(); - ErrorLogging.logError("DEBUG: END OF PROGRAM."); - ErrorLogging.closeLogs(); + close(); } } @@ -441,7 +437,7 @@ public class Cli /** * Starts running tests */ - private static void runTests() + public static void runTests() { DataSaving.initWorkbook(ConfigFacade.getOutputSaveLocation()); boolean prime = false; @@ -470,6 +466,15 @@ public class Cli println("Tests complete!"); } + public static void close() + { + ErrorLogging.logError("DEBUG: PROGRAM CLOSING."); + inputScanner.close(); + MovementFacade.closeGPIO(); + ErrorLogging.logError("DEBUG: END OF PROGRAM."); + ErrorLogging.closeLogs(); + } + /** * Parse the user's input at the main menu, and check it for errors. * diff --git a/src/main/java/org/baxter/disco/ocr/Gui.java b/src/main/java/org/baxter/disco/ocr/Gui.java index 049e3b9..574017c 100644 --- a/src/main/java/org/baxter/disco/ocr/Gui.java +++ b/src/main/java/org/baxter/disco/ocr/Gui.java @@ -1,13 +1,261 @@ package org.baxter.disco.ocr; +import org.bytedeco.opencv.opencv_saliency.StaticSaliency; + +import javafx.application.Application; import javafx.event.*; import javafx.fxml.*; +import javafx.geometry.Orientation; +import javafx.geometry.Pos; import javafx.scene.*; +import javafx.scene.control.Button; +import javafx.scene.control.CheckBox; +import javafx.scene.control.Label; +import javafx.scene.control.Separator; +import javafx.scene.control.TextField; +import javafx.scene.control.Tooltip; +import javafx.scene.image.ImageView; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Pane; +import javafx.scene.layout.Region; +import javafx.scene.layout.VBox; +import javafx.scene.text.Font; import javafx.scene.text.Text; +import javafx.stage.Stage; -/** - * To be implemented. +/**To be implemented; + * GUI for the underlying functions. + * + * @author Blizzard Finnegan + * @version 0.1.0, 30 Jan, 2023 + * */ -public class Gui +public class Gui extends Application { + public static final Scene MAIN_MENU; + private static final AnchorPane MAIN_ANCHOR; + private static final Pane MAIN_PANE; + + public static final Scene CAMERA_MENU; + private static final AnchorPane CAMERA_ANCHOR; + private static final Pane CAMERA_PANE; + + private static Stage STAGE; + + private static int iterationCount = 3; + + public static void main(String[] args) + { launch(args); } + + static + { + MAIN_ANCHOR = new AnchorPane(); + MAIN_ANCHOR.setMinWidth(Double.NEGATIVE_INFINITY); + MAIN_ANCHOR.setMinHeight(Double.NEGATIVE_INFINITY); + MAIN_PANE = new Pane(); + AnchorPane.setTopAnchor(MAIN_PANE,10.0); + AnchorPane.setLeftAnchor(MAIN_PANE,10.0); + AnchorPane.setRightAnchor(MAIN_PANE,10.0); + AnchorPane.setBottomAnchor(MAIN_PANE,10.0); + MAIN_ANCHOR.getChildren().add(MAIN_PANE); + MAIN_MENU = new Scene(MAIN_ANCHOR); + + CAMERA_ANCHOR = new AnchorPane(); + CAMERA_ANCHOR.setMinWidth(Double.NEGATIVE_INFINITY); + CAMERA_ANCHOR.setMinHeight(Double.NEGATIVE_INFINITY); + CAMERA_PANE = new Pane(); + AnchorPane.setTopAnchor(CAMERA_PANE,10.0); + AnchorPane.setLeftAnchor(CAMERA_PANE,10.0); + AnchorPane.setRightAnchor(CAMERA_PANE,10.0); + AnchorPane.setBottomAnchor(CAMERA_PANE,10.0); + CAMERA_ANCHOR.getChildren().add(CAMERA_PANE); + CAMERA_MENU = new Scene(CAMERA_ANCHOR); + } + + @Override + public void start(Stage stage) throws Exception + { + STAGE = stage; + mainMenuBuilder(); + cameraMenuBuilder(); + STAGE.setScene(MAIN_MENU); + } + + private static void cameraMenuBuilder() + { + } + + private static void mainMenuBuilder() + { + VBox layout = new VBox(); + layout.getChildren().addAll(topHalf(),new Separator(Orientation.HORIZONTAL),bottomHalf()); + MAIN_ANCHOR.getChildren().add(layout); + } + + + private static VBox topHalf() + { + VBox output = new VBox(); + output.getChildren().addAll(topButtons(),new Separator(Orientation.HORIZONTAL),setupSection(),primeCheckbox(),testFeedback()); + return topHalf(); + } + + private static CheckBox primeCheckbox() + { + CheckBox output = new CheckBox("Prime devices (pushes button twice)"); + output.setId("primeCheckbox"); + return output; + } + + private static HBox testFeedback() + { + HBox output = new HBox(); + + Label textboxLabel = new Label("Test feedback: "); + Text textbox = new Text("Awaiting input..."); + textbox.setId("testOutputToUser"); + + output.getChildren().addAll(textboxLabel,textbox); + return output; + } + + private static HBox setupSection() + { + return userTextbox("Cycles",Integer.toString(iterationCount), "Enter the number of times to test the devices in the fixture."); + } + + private static HBox userTextbox(String prompt, String baseValue, String description) + { + HBox output = new HBox(); + Label label = new Label(prompt); + TextField field = new TextField(); + field.setId(prompt.toLowerCase()); + field.setPromptText(baseValue); + Tooltip tooltip = new Tooltip(description); + field.setTooltip(tooltip); + label.setTooltip(tooltip); + output.getChildren().addAll(label,field); + return output; + } + + private static HBox topButtons() + { + HBox topButtons = new HBox(); + topButtons.setAlignment(Pos.CENTER); + topButtons.setMinWidth(Region.USE_COMPUTED_SIZE); + topButtons.setMinHeight(Region.USE_COMPUTED_SIZE); + + Button start = buttonBuilder("Start",true); + buttonBuilder("Start",true); + start.setOnAction( + new EventHandler() + { + @Override + public void handle(ActionEvent event) + { + Cli.runTests(); + } + }); + + Button stop = buttonBuilder("Stop",true); + stop.setOnAction( + new EventHandler() + { + @Override + public void handle(ActionEvent event) + { + Cli.close(); + } + }); + Button calibrateCamera = buttonBuilder("Calibrate Cameras",false); + calibrateCamera.setOnAction( + new EventHandler() + { + @Override + public void handle(ActionEvent event) + { + STAGE.setScene(CAMERA_MENU); + } + }); + Button testMovement = buttonBuilder("Test Movement",false); + testMovement.setOnAction( + new EventHandler() + { + @Override + public void handle(ActionEvent event) + { + MovementFacade.testMotions(); + } + }); + + Button cancel = buttonBuilder("Close",false); + cancel.setOnAction( + new EventHandler() + { + @Override + public void handle(ActionEvent event) + { + Cli.close(); + } + }); + + + topButtons.getChildren().addAll(start,stop,calibrateCamera,testMovement,cancel); + return topButtons; + } + + private static HBox bottomHalf() + { + HBox output = new HBox(); + output.getChildren().addAll(camera(1),new Separator(Orientation.VERTICAL),camera(2)); + return output; + } + + private static VBox camera(int number) + { + VBox output = new VBox(); + HBox serialNumber = userTextbox("DUT Serial Number:","","Enter the serial number for the device under test."); + output.getChildren().addAll(cameraHeader(number),serialNumber,cameraView(number)); + return output; + } + + private static HBox cameraHeader(int number) + { + HBox output = new HBox(); + output.getChildren().addAll(cameraCheckbox("Camera " + number)); + return output; + } + + private static HBox cameraCheckbox(String prompt) + { + HBox output = new HBox(); + output.setAlignment(Pos.CENTER); + Label label = new Label(prompt); + CheckBox checkBox = new CheckBox("Active"); + checkBox.setId(prompt.toLowerCase()); + output.getChildren().addAll(label,checkBox); + return output; + } + + private static HBox cameraView(int number) + { + HBox output = new HBox(); + output.setAlignment(Pos.CENTER_LEFT); + Label label = new Label("OCR Read:"); + Label ocrRead = new Label("[ ]"); + ocrRead.setId("cameraOCR" + number); + ImageView imageView = new ImageView(); + output.getChildren().addAll(label,ocrRead,imageView); + return output; + } + + private static Button buttonBuilder(String name,boolean disabled) + { + Button button = new Button(name); + button.setId(name.toLowerCase()); + button.setFont(Font.getDefault()); + if (disabled) button.disableProperty(); + return button; + } } diff --git a/src/main/java/org/baxter/disco/ocr/GuiStarter.java b/src/main/java/org/baxter/disco/ocr/GuiStarter.java new file mode 100644 index 0000000..0ad2ed2 --- /dev/null +++ b/src/main/java/org/baxter/disco/ocr/GuiStarter.java @@ -0,0 +1,18 @@ +package org.baxter.disco.ocr; + +/** + * Wrapper class around Gui. + * + * Maven will not build the {@link Gui} properly, since it inherits from {@link javafx.application.Application}. + * This will start the Gui's main function, with no other functionality. + * + * @author Blizzard Finnegan + * @version 1.0.0, 30 Jan. 2023 + */ +public class GuiStarter +{ + public static void main(String[] args) + { + Gui.main(args); + } +} diff --git a/src/main/java/org/baxter/disco/ocr/cameraTest.fxml b/src/main/java/org/baxter/disco/ocr/cameraTest.fxml deleted file mode 100644 index 138b7c3..0000000 --- a/src/main/java/org/baxter/disco/ocr/cameraTest.fxml +++ /dev/null @@ -1,151 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -