diff --git a/pom.xml b/pom.xml index 680b9ad5b923a384115bb376c477879ec0abd7d2..00cb5b1fa8a05d0223c1cd099fac042158a1340f 100644 --- a/pom.xml +++ b/pom.xml @@ -56,6 +56,12 @@ <version>4.12</version> <scope>test</scope> </dependency> + <!-- https://mvnrepository.com/artifact/org.controlsfx/controlsfx --> + <dependency> + <groupId>org.controlsfx</groupId> + <artifactId>controlsfx</artifactId> + <version>11.0.0</version> + </dependency> </dependencies> <build> <plugins> diff --git a/src/main/java/projekt/enigma/App.java b/src/main/java/projekt/enigma/App.java index eff5d686c3144f8f32d639b336b25cc855998093..03f9260b62accc6a2544ef476fa58c3fb9082b91 100644 --- a/src/main/java/projekt/enigma/App.java +++ b/src/main/java/projekt/enigma/App.java @@ -2,9 +2,14 @@ package projekt.enigma; import javafx.application.Application; import javafx.fxml.FXMLLoader; -import javafx.scene.Parent; import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.scene.input.KeyCode; +import javafx.scene.layout.VBox; import javafx.stage.Stage; +import projekt.enigma.model.Fehler; import java.io.IOException; @@ -15,60 +20,135 @@ import java.io.IOException; */ public class App extends Application { - /** - * TODO Dokumentieren - * - * scene : Scene : deklariert die Scene der GUI - */ - private static Scene scene; - - /** - * TODO Dokumentieren - * setzt die fxml-Datei - * - * @param fxml : String : Ort der fxml - * @throws IOException : wirft Exception, wenn die Datei nicht gefunden/geladen werden konnte - */ - static void setRoot(String fxml) throws IOException { - scene.setRoot(loadFXML(fxml)); - } + private static String kenngruppe; + private static GuiController gc; + private static int debug; - /** - * TODO Dokumentieren - * laedt die fxml-Datei - * - * @param fxml : String : Ort der fxml - * @return fxml wird geladen - * @throws IOException : wirft Exception, wenn die Datei nicht gefunden/geladen werden konnte - */ - private static Parent loadFXML(String fxml) throws IOException { - FXMLLoader fxmlLoader = new FXMLLoader(App.class.getResource(fxml + ".fxml")); - return fxmlLoader.load(); + public static void main(String[] args) { + debug = 1; + launch(args); } - /** - * TODO Dokumentieren - * Standard-main-Methode, die die erweiterte Klasse Application startet - * - * @param args : String[] : Terminalparameter - */ - public static void main(String[] args) { - Application.launch(); + public static int getDebug() { + return debug; } - /** - * TODO Dokumentieren - * Deklariert und initialisiert die Stage. - * - * @param stage : Stage : Aufbau der Stage in der Scene - * @throws IOException : wirft Exception, wenn die Datei nicht gefunden/geladen werden konnte - */ @Override - public void start(Stage stage) throws IOException { - scene = new Scene(loadFXML("kenngruppe")); - stage.setScene(scene); - stage.setResizable(true); - stage.show(); + public void start(Stage primaryStage) throws IOException { + + primaryStage.setTitle("Kenngruppenabfrage"); + + Label label1 = new Label("Bitte Kenngruppe eingeben!"); + label1.setTranslateX(55); + Label l1 = new Label(""); + Label l2 = new Label(""); + TextField tfield = new TextField(); + Button button1 = new Button("Kenngruppe setzen!"); + VBox layout1 = new VBox(); + + layout1.getChildren().addAll(label1, l1, tfield, l2, button1); + Scene sceKenngruppe = new Scene(layout1, 234, 137); + + FXMLLoader guiLoader = new FXMLLoader(App.class.getResource("gui.fxml")); + + Scene sceApp = new Scene(guiLoader.load(), 962, 677); + + tfield.setOnKeyPressed(e -> { + if (e.getCode() == KeyCode.ENTER) { + if (enter(tfield.getText())) { + gc = guiLoader.getController(); + gc.setKenngruppe(tfield.getText()); + primaryStage.setScene(sceApp); + } else { + tfield.setText(""); + new Fehler().showErrorDialog("error", "Kenngruppe falsch", + "Regeln für die Kenngruppe: 4-8 Zeichen sowie nur Buchstaben von A-Z."); + } + } + }); + + button1.setOnAction(e -> { + if (enter(tfield.getText())) { + gc = guiLoader.getController(); + gc.setKenngruppe(tfield.getText()); + primaryStage.setScene(sceApp); + } else { + tfield.setText(""); + new Fehler().showErrorDialog("error", "Kenngruppe falsch", + "Regeln für die Kenngruppe: 4-8 Zeichen sowie Buchstaben von A-Z."); + } + }); + + primaryStage.setScene(sceKenngruppe); + primaryStage.show(); + } + + private boolean enter(String kenngruppe) { + + String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + boolean result = true; + + for (char c : kenngruppe.toUpperCase().toCharArray()) { + if (!alphabet.contains(String.valueOf(c))) { + result = false; + break; + } + } + if (kenngruppe.length() > 8 || kenngruppe.length() < 4) { + result = false; + } + + return result; } +// /** +// * TODO Dokumentieren +// */ +// private static Scene scene; +// /** +// * TODO Dokumentieren +// * +// * @param fxml +// * @throws IOException +// */ +// static void setRoot(String fxml) throws IOException { +// scene.setRoot(loadFXML(fxml)); +// +// } +// +// /** +// * TODO Dokumentieren +// * +// * @param fxml +// * @return +// * @throws IOException +// */ +// private static Parent loadFXML(String fxml) throws IOException { +// FXMLLoader fxmlLoader = new FXMLLoader(App.class.getResource(fxml + ".fxml")); +// return fxmlLoader.load(); +// } +// +// /** +// * TODO Dokumentieren +// * +// * @param args +// */ +// public static void main(String[] args) { +// Application.launch(); +// } +// +// /** +// * TODO Dokumentieren +// * +// * @param stage +// * @throws IOException +// */ +// @Override +// public void start(Stage stage) throws IOException { +// scene = new Scene(loadFXML("kenngruppe")); +// stage.setScene(scene); +// stage.setResizable(true); +// stage.show(); +// } + } diff --git a/src/main/java/projekt/enigma/GuiController.java b/src/main/java/projekt/enigma/GuiController.java index d7fa06f1c82efb98033abaf7d37fcaaa6260d7f0..024e2aa1a5327278b7f1daa5dac52e6c8d17762c 100644 --- a/src/main/java/projekt/enigma/GuiController.java +++ b/src/main/java/projekt/enigma/GuiController.java @@ -1,696 +1,818 @@ package projekt.enigma; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.concurrent.Task; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.*; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.MenuItem; +import javafx.scene.control.TextField; import javafx.scene.input.MouseEvent; +import javafx.scene.layout.GridPane; import javafx.scene.shape.Circle; +import javafx.stage.StageStyle; import org.apache.http.HttpException; +import org.controlsfx.control.CheckComboBox; +import org.controlsfx.dialog.ProgressDialog; import projekt.enigma.model.Codierer; +import projekt.enigma.model.Fehler; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; public class GuiController { - //region Klassenvariablen - private final static String[] walzenNr = {"I", "II", "III", "IV", "V"}; - private final static String[] ringNr = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26"}; - private final static String[] position = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}; - private ArrayList<MenuItem> mItem; - private String textEingabe; - private String textCodiert; - private boolean resetDisplay; - private Codierer codierer; - private char chiffrierterBuchstabe; - //deklariert die benötigten Textfelder - @FXML - private TextField tfStecker1, tfStecker2, tfStecker3, tfStecker4, tfStecker5, tfStecker6, tfStecker7, tfStecker8, - tfStecker9, tfStecker10, tfCodiert, tfKlartext; + //region Klassenvariablen + private final static String[] walzenNr = {"I", "II", "III", "IV", "V"}; + private final static String[] ringNr = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26"}; + private final static String[] position = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}; + private ArrayList<MenuItem> mItem; + private String textEingabe; + private String textCodiert; + private boolean resetDisplay; + private Codierer codierer; + private char chiffrierterBuchstabe; + private String[] empfangeneNachricht; + //deklariert die benötigten Textfelder + @FXML + private TextField tfStecker1, tfStecker2, tfStecker3, tfStecker4, tfStecker5, tfStecker6, tfStecker7, tfStecker8, + tfStecker9, tfStecker10, tfCodiert, tfKlartext; //endregion - //region GUI-Elemente - - //deklariert die benötigten Buttons - @FXML - private Button btnA, btnB, btnC, btnD, btnE, btnF, btnG, btnH, btnI, btnJ, btnK, btnL, btnM, btnN, btnO, btnP, btnQ, - btnR, btnS, btnT, btnU, btnV, btnW, btnX, btnY, btnZ, btnSenden, btnEmpfangen, btnDelete, btnReset; - //deklariert die benötigten Kreise - @FXML - private Circle circA, circB, circC, circD, circE, circF, circG, circH, circI, circJ, circK, circL, circM, circN, - circO, circP, circQ, circR, circS, circT, circU, circV, circW, circX, circY, circZ; - //deklariert die benötigten Label - @FXML - private Label lblA, lblB, lblC, lblD, lblE, lblF, lblG, lblH, lblI, lblJ, lblK, lblL, lblM, lblN, lblO, lblP, lblQ, - lblR, lblS, lblT, lblU, lblV, lblW, lblX, lblY, lblZ, lblLadeNachricht, lblTagesschluessel, - lblSpruchschluessel; - //deklariert die ProgressBar - @FXML - private ProgressBar pbLadeNachricht; - //deklariert die MenueButtons - @FXML - private MenuButton mBtnWalzPos1, mBtnWalzPos2, mBtnWalzPos3, mBtnNotchPos1, mBtnNotchPos2, mBtnNotchPos3, - mBtnStartPos1, mBtnStartPos2, mBtnStartPos3; - - /** - * Initialisiert die Elemente GUI und setzt deren Startwerte - */ - @FXML - void initialize() { - - // Variablen setzen - textEingabe = ""; - textCodiert = ""; - resetDisplay = true; - - //Einträge für Walzen - menu(mBtnWalzPos1, walzenNr); - menu(mBtnWalzPos2, walzenNr); - menu(mBtnWalzPos3, walzenNr); - - //Einträge für die Ringe - menu(mBtnNotchPos1, ringNr); - menu(mBtnNotchPos2, ringNr); - menu(mBtnNotchPos3, ringNr); - - //Einträge für die Startpositionen - menu(mBtnStartPos1, position); - menu(mBtnStartPos3, position); - menu(mBtnStartPos2, position); - - // Initialisieren des Codierers und setzen der Kenngruppe - codierer = new Codierer(); - if(codierer.getKenngruppe().equals(""))codierer.setKenngruppe("enigma"); - else codierer.getKenngruppe(); - - // Beim nächsten Tastendruck erstmal das Display löschen damit falschen Nachrichten geschickt werden. - resetDisplay = true; - - // Einstellungen aus dem Logbuch auslesen und setzen - setzeTagesSchluessel(); - setzeSteckverbindungen(); - } -//endregion - - //region Init - - /** - * init Methode zur Erstellung der Einträge und Action Listener für die einzelnen Menüs - * - * @param button : Button für die die Einträge erstellt werden sollen - */ - private void menu(MenuButton button, String[] str) { - mItem = new ArrayList<>(); - for (int i = 0; i < str.length; i++) { - //Eintrag aus str der Arraylist mi hinzufügen - mItem.add(new MenuItem(str[i])); - //MenuItem mi dem Button button hinzufügen - button.getItems().add(mItem.get(i)); - int finalI = i; - //Listener für die einzelnen Einträge - ArrayList<MenuItem> finalMi = mItem; - mItem.get(i).setOnAction(e -> setMenuBtnText(button, finalMi.get(finalI))); - } - } - - /** - * Wird ausgelöst wenn der gedrückte Button losgelassen wird. - * Setzt die Hintergrundfarbe des Kreises mit dem chiffrierten Buchstaben auf grau, - * durch Aufruf der Methode leuchten. - * - * @param e => übergibt den zuletzt losgelassenen Button - */ - @FXML - void tasteRauf(MouseEvent e) { - if (e.getSource() == btnA) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnB) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnC) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnD) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnE) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnF) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnG) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnH) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnI) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnJ) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnK) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnL) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnM) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnN) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnO) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnP) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnQ) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnR) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnS) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnT) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnU) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnV) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnW) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnX) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnY) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnZ) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - } -//endregion + //region GUI-Elemente + + //deklariert die benötigten Buttons + @FXML + private Button btnA, btnB, btnC, btnD, btnE, btnF, btnG, btnH, btnI, btnJ, btnK, btnL, btnM, btnN, btnO, btnP, btnQ, + btnR, btnS, btnT, btnU, btnV, btnW, btnX, btnY, btnZ, btnSenden, btnEmpfangen, btnDelete, btnReset; + //deklariert die benötigten Kreise + @FXML + private Circle circA, circB, circC, circD, circE, circF, circG, circH, circI, circJ, circK, circL, circM, circN, + circO, circP, circQ, circR, circS, circT, circU, circV, circW, circX, circY, circZ; + //deklariert die benötigten Label + @FXML + private Label lblA, lblB, lblC, lblD, lblE, lblF, lblG, lblH, lblI, lblJ, lblK, lblL, lblM, lblN, lblO, lblP, lblQ, + lblR, lblS, lblT, lblU, lblV, lblW, lblX, lblY, lblZ, lblLadeNachricht, lblTagesschluessel, + lblSpruchschluessel; + //deklariert die ProgressBar + @FXML + private ProgressBar pbLadeNachricht; + //deklariert die MenueButtons + @FXML + private MenuButton mBtnWalzPos1, mBtnWalzPos2, mBtnWalzPos3, mBtnNotchPos1, mBtnNotchPos2, mBtnNotchPos3, + mBtnStartPos1, mBtnStartPos2, mBtnStartPos3; + + @FXML + private GridPane mainGrid; + + private static final String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - //region EventHandler/Listener - - /** - * Wird ausgelöst sobald eine Taste gedrückt wird (beim drücken der Taste) - * Auswertung welche Buchstaben-Taste gedrückt ist. - * Übergabe des entspechenden Buchstaben als Parameter der Methode setText welche den chiffrierten Buchstaben - * in der Klassen-Variablen chiffrierterBuchstabe ablegt. - * Setzt die Hintergrundfarbe des Kreises mit dem chiffrierten Buchstaben auf gelb - * - * @param e => übergibt den momentan gedrückten Buttons - */ - @FXML - void tasteRunter(MouseEvent e) { - if (e.getSource() == btnA) { - setText(btnA); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnB) { - setText(btnB); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnC) { - setText(btnC); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnD) { - setText(btnD); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnE) { - setText(btnE); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnF) { - setText(btnF); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnG) { - setText(btnG); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnH) { - setText(btnH); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnI) { - setText(btnI); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnJ) { - setText(btnJ); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnK) { - setText(btnK); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnL) { - setText(btnL); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnM) { - setText(btnM); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnN) { - setText(btnN); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnO) { - setText(btnO); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnP) { - setText(btnP); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnQ) { - setText(btnQ); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnR) { - setText(btnR); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnS) { - setText(btnS); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnT) { - setText(btnT); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnU) { - setText(btnU); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnV) { - setText(btnV); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnW) { - setText(btnW); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnX) { - setText(btnX); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnY) { - setText(btnY); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnZ) { - setText(btnZ); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } -/* if (e.getSource() == btnSenden)sendeFunkspruch(); - if (e.getSource() == btnEmpfangen) empfangeFunkspruch(); - if (e.getSource() == btnDelete) loeschen();*/ - } - - /** - * Auswertung welcher Button (senden, empfangen oder löschen) gedrückt wurde. - * Funktionsaufruf entsprechend des gedrückten Button - * - * @param e => ActionEvent des auslösenden Button - */ - @FXML - private void gedrueckteTaste(ActionEvent e) { - if (e.getSource() == btnSenden && tfCodiert.getText() != "") sendeFunkspruch(); - if (e.getSource() == btnEmpfangen) empfangeFunkspruch(); - if (e.getSource() == btnDelete) loeschen(); - if (e.getSource() == btnReset) { - codierer.resetHardware(); - this.resetDisplay = true; - this.setzeTagesSchluessel(); - } - } - - /** - * Setzt die Hintergrundfarbe des Kreises (chiffrierter Buchstabe) auf gelb bzw. auf grau. - * - * @param leuchte => gibt an welcher Kreis (chiffrierter Buchstabe) den Hintergrund ändern soll - * @param shiningLetter => "AN" -> setzt Hintergrundfarbe des Kreises (chiffrierter Buchstabe) auf gelb - * "AUS" -> setzt Hintergrundfarbe des Kreises (chiffrierter Buchstabe) auf grau - */ - private void leuchten(Circle leuchte, BUCHSTABE_LEUCHTET shiningLetter) { - if (shiningLetter == BUCHSTABE_LEUCHTET.AN) leuchte.setStyle("-fx-fill: #FFA500"); - else if (shiningLetter == BUCHSTABE_LEUCHTET.AUS) { - leuchte.setStyle("-fx-background-color: grey"); - leuchte.setStyle("-fx-border-color: #000000"); - } - } //endregion - //region Methoden - - /** - * Gibt den Buchstabenkreis entsprechend des chiffrierten Buchstabens zurück - * - * @param chiffLetter => chiffrierter Buchstabe - * @return => Kreis des chiffrierten Buchstabens (der leuchten soll) - */ - private Circle chiffCircle(char chiffLetter) { - switch (chiffLetter) { - case 'A': - return circA; - case 'B': - return circB; - case 'C': - return circC; - case 'D': - return circD; - case 'E': - return circE; - case 'F': - return circF; - case 'G': - return circG; - case 'H': - return circH; - case 'I': - return circI; - case 'J': - return circJ; - case 'K': - return circK; - case 'L': - return circL; - case 'M': - return circM; - case 'N': - return circN; - case 'O': - return circO; - case 'P': - return circP; - case 'Q': - return circQ; - case 'R': - return circR; - case 'S': - return circS; - case 'T': - return circT; - case 'U': - return circU; - case 'V': - return circV; - case 'W': - return circW; - case 'X': - return circX; - case 'Y': - return circY; - case 'Z': - return circZ; - } - return null; - } - - /** - * Methode zum setzen des menuButton Textes auf das ausgewählte MenuItem - * - * @param mBtn : MenuButton der Walze - * @param mItm : MenuItem - */ - private void setMenuBtnText(MenuButton mBtn, MenuItem mItm) { - // mb.setText(mi.getText()); - - if (mBtn.getId().equals(mBtnStartPos1.getId())) setzePosition(1, mItm.getText().charAt(0)); - if (mBtn.getId().equals(mBtnStartPos2.getId())) setzePosition(2, mItm.getText().charAt(0)); - if (mBtn.getId().equals(mBtnStartPos3.getId())) setzePosition(3, mItm.getText().charAt(0)); - if (mBtn.getId().equals(mBtnWalzPos1.getId())) setzeWalze(1, mItm.getText()); - if (mBtn.getId().equals(mBtnWalzPos2.getId())) setzeWalze(2, mItm.getText()); - if (mBtn.getId().equals(mBtnWalzPos3.getId())) setzeWalze(3, mItm.getText()); - if (mBtn.getId().equals(mBtnNotchPos1.getId())) - setzeRing(1, Integer.parseInt(mItm.getText()) - 1); - if (mBtn.getId().equals(mBtnNotchPos2.getId())) - setzeRing(2, Integer.parseInt(mItm.getText()) - 1); - if (mBtn.getId().equals(mBtnNotchPos3.getId())) - setzeRing(3, Integer.parseInt(mItm.getText()) - 1); -/* tfCodiert.setText(""); - tfKlartext.setText("");*/ - } - - /** - * Hier werden die TextFelder, welche die Steckverbindungen darstellen, - * mit dem Werten die die Klasse Codierer zur Verfügung stellt gefüllt. - */ - private void setzeSteckverbindungen() { - tfStecker1.setText(codierer.fetchSteckverbindungen()[0][0] + "" + codierer.fetchSteckverbindungen()[0][1]); - tfStecker2.setText(codierer.fetchSteckverbindungen()[1][0] + "" + codierer.fetchSteckverbindungen()[1][1]); - tfStecker3.setText(codierer.fetchSteckverbindungen()[2][0] + "" + codierer.fetchSteckverbindungen()[2][1]); - tfStecker4.setText(codierer.fetchSteckverbindungen()[3][0] + "" + codierer.fetchSteckverbindungen()[3][1]); - tfStecker5.setText(codierer.fetchSteckverbindungen()[4][0] + "" + codierer.fetchSteckverbindungen()[4][1]); - tfStecker6.setText(codierer.fetchSteckverbindungen()[5][0] + "" + codierer.fetchSteckverbindungen()[5][1]); - tfStecker7.setText(codierer.fetchSteckverbindungen()[6][0] + "" + codierer.fetchSteckverbindungen()[6][1]); - tfStecker8.setText(codierer.fetchSteckverbindungen()[7][0] + "" + codierer.fetchSteckverbindungen()[7][1]); - tfStecker9.setText(codierer.fetchSteckverbindungen()[8][0] + "" + codierer.fetchSteckverbindungen()[8][1]); - tfStecker10.setText(codierer.fetchSteckverbindungen()[9][0] + "" + codierer.fetchSteckverbindungen()[9][1]); - } - - /** - * Die Löschen Funktion löscht das letzte Zeichen im Klartext sowie im Codiert Feld, - * der Codierer wird aufgerufen um ebenfalls das letzte Zeichen zu löschen - */ - private void loeschen() { - if (textEingabe.length() == 0) { - tfKlartext.setText(""); - tfCodiert.setText(""); - } else { - textEingabe = textEingabe.substring(0, textEingabe.length() - 1); - textCodiert = textCodiert.substring(0, textCodiert.length() - 1); - tfKlartext.setText(textEingabe); - tfCodiert.setText(textCodiert); - codierer.letztesZeichenLoeschen(); - mBtnStartPos1.setText(String.valueOf(this.codierer.fetchWalzen()[0])); - mBtnStartPos2.setText(String.valueOf(this.codierer.fetchWalzen()[1])); - mBtnStartPos3.setText(String.valueOf(this.codierer.fetchWalzen()[2])); - } - } - - /** - * Holt Nachricht von Klasse Codierer und setzt den chiffrierten Text in das Textfeld tfCodiert, - * sowie den Klartext in das Textfeld tfKlartext. Setzt den Spruchschlüssel - */ - private void empfangeFunkspruch() { - String[] empfangeneNachricht = codierer.empfangeNachricht(); - System.out.println("text: " + empfangeneNachricht[0]); - System.out.println("Klartext: " + empfangeneNachricht[2]); - System.out.println("codiert: " + empfangeneNachricht[1]); - if (empfangeneNachricht[0]!=null) { - setzeTagesSchluessel(); - System.out.println("empfange Nachricht"); - tfKlartext.setText(empfangeneNachricht[2]); - tfCodiert.setText(empfangeneNachricht[1]); - resetDisplay = true; - - // Spruchschluessel in das Feld lblSpruchschluessel schreiben - lblSpruchschluessel.setText(codierer.empfangenerSpruchschluessel(empfangeneNachricht[2])); - - - } - } - - /** - * Senden der Nachricht mit Hilfe der Klasse Codierer - * Löscht die Textfelder tfKlartext und tfCodiert - */ - private void sendeFunkspruch() { - this.tfKlartext.setText(""); - this.tfCodiert.setText(""); - - try { - this.codierer.sendeNachricht(); - } catch (HttpException | IOException e) { - e.printStackTrace(); - } - - } - - /** - * Schreibt Buchstaben des gedrückten Button in Textfeld tfKlartext. - * Übergabe des Buchstaben vom gedrückten Button an die Klasse Codierer - * Ablegen des chiffrierten Buchstaben in der char Variable chiffrierterBuchstabe - * Hinzufügen des chiffrierten Buchstaben in Textfeld tfCodiert - * Aktualisierung der Walzenstellung - * - * @param pressedButton : gedrückter Knopf - */ - private void setText(Button pressedButton) { - if (textEingabe.length() < 250) { - if (this.resetDisplay) { - this.tfCodiert.setText(""); - this.tfKlartext.setText(""); - this.resetDisplay = false; - this.codierer.resetHardware(); - textCodiert = ""; - textEingabe = ""; - // Spruchschlüssel generieren und codieren - this.codierer.generateSpruchschluessel(); - // Spruchschluessel in das Feld lblSpruchschluessel schreiben - lblSpruchschluessel.setText(this.codierer.getSpruchschluessel()); - } - textEingabe += pressedButton.getText(); - chiffrierterBuchstabe = codierer.codiere(pressedButton.getText().charAt(0), true); - textCodiert += chiffrierterBuchstabe; - - tfKlartext.setText(textEingabe); - tfCodiert.setText(textCodiert); - - // Position der Walzen aktuallisieren - mBtnStartPos1.setText(String.valueOf(this.codierer.fetchWalzen()[0])); - mBtnStartPos2.setText(String.valueOf(this.codierer.fetchWalzen()[1])); - mBtnStartPos3.setText(String.valueOf(this.codierer.fetchWalzen()[2])); - } - } - - /** - * Setzt die Anzeige des entsprechende Gui-Element auf die entsprechende Walze - * ->d.h. welche Walze sitzt auf welcher Position - * - * @param walzeRoemischNr => gibt die Walzennummer an - * @param walzenPosition => gibt die Position der Walze - */ - private void setzeWalze(int walzenPosition, String walzeRoemischNr) { - int walzeNr = 0; - switch (walzeRoemischNr) { - case "I": - walzeNr = 0; - break; - case "II": - walzeNr = 1; - break; - case "III": - walzeNr = 2; - break; - case "IV": - walzeNr = 4; - break; - case "V": - walzeNr = 4; - break; - default: - break; - } - - switch (walzenPosition) { - case 1: - mBtnWalzPos1.setText(walzenNr[walzeNr]); - //codierer.setWalze(walzeNr, walzenPosition) - break; - case 2: - mBtnWalzPos2.setText(walzenNr[walzeNr]); - break; - case 3: - mBtnWalzPos3.setText(walzenNr[walzeNr]); - break; - default: - break; - } - } - - /** - * Setzt die Anzeige des entsprechende Gui-Element auf die entsprechende Walze - * -> d.h. welche Walze sitzt auf welcher Position - * - * @param walzenPosition => gibt die Position der Walze - * @param walzeNr => gibt die Walzennummer an - */ - private void setzeWalze(int walzenPosition, int walzeNr) { - //int walzeNr = 0; - switch (walzeNr) { - case 1: - walzeNr = 0; - break; - case 2: - walzeNr = 1; - break; - case 3: - walzeNr = 2; - break; - case 4: - walzeNr = 3; - break; - case 5: - walzeNr = 4; - break; - default: - break; - } - - switch (walzenPosition) { - case 1: - mBtnWalzPos1.setText(walzenNr[walzeNr]); - //codierer.setWalze(walzeNr, walzenPosition) - break; - case 2: - mBtnWalzPos2.setText(walzenNr[walzeNr]); - break; - case 3: - mBtnWalzPos3.setText(walzenNr[walzeNr]); - break; - default: - break; - } - } - - /** - * Setzt den Notch (position)=> die Mitnahmeposition der Walze (walze) fest - * Mitnahmeposition meint => die nächste Walze wird bei erreichen dieser Position (notch) - * um eine Stelle versetzt - * - * @param ringStellung => gibt die walze an - * @param walzenPosition => gibt den notch der Walze (walze) an - */ - private void setzeRing(int walzenPosition, int ringStellung) { - switch (walzenPosition) { - case 1: - mBtnNotchPos1.setText(ringNr[ringStellung]); - break; - case 2: - mBtnNotchPos2.setText(ringNr[ringStellung]); - break; - case 3: - mBtnNotchPos3.setText(ringNr[ringStellung]); - break; - default: - break; - } - } - - /** - * Setzt die Startposition/ aktuelle Position der Walze - * - * @param walze => gibt die walze an - * @param buchstabe gibt den Startwert bzw die aktuelle Position der Walze (walze) an - */ - private void setzePosition(int walze, char buchstabe) { - switch (walze) { - case 1: - mBtnStartPos1.setText(String.valueOf(buchstabe)); - break; - case 2: - mBtnStartPos2.setText(buchstabe + ""); - break; - case 3: - mBtnStartPos3.setText(buchstabe + ""); - break; - default: - break; - } - } - - /** - * Setzt den aktuellen TagesSchluessel und zeigt diesen in der GUI an - */ - private void setzeTagesSchluessel() { - - // Umsprungpunkte anzeigen - mBtnNotchPos1.setText(String.valueOf(codierer.fetchRingstellung()[0])); - mBtnNotchPos2.setText(String.valueOf(codierer.fetchRingstellung()[1])); - mBtnNotchPos3.setText(String.valueOf(codierer.fetchRingstellung()[2])); - // Walzennummern anzeigen - setzeWalze(1, codierer.fetchWalzenNr()[0]); - setzeWalze(2, codierer.fetchWalzenNr()[1]); - setzeWalze(3, codierer.fetchWalzenNr()[2]); - // Position der Walzen anzeigen - mBtnStartPos1.setText(String.valueOf(codierer.fetchWalzen()[0])); - mBtnStartPos2.setText(String.valueOf(codierer.fetchWalzen()[1])); - mBtnStartPos3.setText(String.valueOf(codierer.fetchWalzen()[2])); - // Steckbrett Felder setzen - tfStecker1.setText(codierer.fetchSteckverbindungen()[0][0] + "" + - codierer.fetchSteckverbindungen()[0][1]); - tfStecker2.setText(codierer.fetchSteckverbindungen()[1][0] + "" + - codierer.fetchSteckverbindungen()[1][1]); - tfStecker3.setText(codierer.fetchSteckverbindungen()[2][0] + "" + - codierer.fetchSteckverbindungen()[2][1]); - tfStecker4.setText(codierer.fetchSteckverbindungen()[3][0] + "" + - codierer.fetchSteckverbindungen()[3][1]); - tfStecker5.setText(codierer.fetchSteckverbindungen()[4][0] + "" + - codierer.fetchSteckverbindungen()[4][1]); - tfStecker6.setText(codierer.fetchSteckverbindungen()[5][0] + "" + - codierer.fetchSteckverbindungen()[5][1]); - tfStecker7.setText(codierer.fetchSteckverbindungen()[6][0] + "" + - codierer.fetchSteckverbindungen()[6][1]); - tfStecker8.setText(codierer.fetchSteckverbindungen()[7][0] + "" + - codierer.fetchSteckverbindungen()[7][1]); - tfStecker9.setText(codierer.fetchSteckverbindungen()[8][0] + "" + - codierer.fetchSteckverbindungen()[8][1]); - tfStecker10.setText(codierer.fetchSteckverbindungen()[9][0] + "" + - codierer.fetchSteckverbindungen()[9][1]); - this.textCodiert = ""; - this.textEingabe = ""; - this.tfKlartext.setText(""); - this.tfCodiert.setText(""); - } - - private enum BUCHSTABE_LEUCHTET {AN, AUS} - //endregion + //region Init + + /** + * Initialisiert die Elemente GUI und setzt deren Startwerte + */ + @FXML + void initialize() { + + // Variablen setzen + textEingabe = ""; + textCodiert = ""; + resetDisplay = true; + + //Einträge für Walzen + menu(mBtnWalzPos1, walzenNr); + menu(mBtnWalzPos2, walzenNr); + menu(mBtnWalzPos3, walzenNr); + + //Einträge für die Ringe + menu(mBtnNotchPos1, ringNr); + menu(mBtnNotchPos2, ringNr); + menu(mBtnNotchPos3, ringNr); + + //Einträge für die Startpositionen + menu(mBtnStartPos1, position); + menu(mBtnStartPos3, position); + menu(mBtnStartPos2, position); + } + + /** + * Für das Steckbrett müssen zehn CheckComboBoxen erstellt werden. + * Hier wird die Funktion zum erstellen und Befüllen der Boxen, die Funktion zehn mal aufgerufen. + */ + private void generateSteckbrett() { + + for (int i = 0; i <= 9; i++) { + this.createSteckbrettPort(i); + } + } + + /** + * Die Funktion createSteckbrettPort erstellt zehn CheckComboBoxen, holt sich die verfügbaren Buchstaben, + * die bereits gesteckten Kabel und weißt sie zu. + * Im Anschluss werden die CheckComboBoxen auf dem GridPane positioniert. + * + * @param port : int : Kabel Nummer (0-9) + */ + private void createSteckbrettPort(int port) { + + // Item Liste anlegen + ObservableList<Character> items = FXCollections.observableArrayList(); + + // Holt die verfügbaren Buchstaben für diesen Port ab und erstellt ein char Array daraus + char[] verfuegbareBuchstaben = this.codierer.fetchVerfuegbareBuchstaben(port).toCharArray(); + + // Sortiert das Array nach dem Alphabet + Arrays.sort(verfuegbareBuchstaben); + + StringBuilder sb = new StringBuilder(); + + /** + * Die Buchstaben in die CheckComboBox laden und zusätzlich in einen String um später den + * Index des Buchstaben auslesen zu können + */ + for (char c : verfuegbareBuchstaben) { + items.add(c); + sb.append(c); + } + + // Eine CheckComboBox erstellen + CheckComboBox<Character> ccb = new CheckComboBox<Character>(items); + + // Die CheckComboBox dem GridPane in der Oberfläche zuordnen + mainGrid.add(ccb, 1 + port, 8); + + // Die Gesteckten Buchstaben in der CheckComboBox selektieren + ccb.getCheckModel().check(sb.toString().indexOf(this.codierer.fetchSteckverbindungen()[port][0])); + ccb.getCheckModel().check(sb.toString().indexOf(this.codierer.fetchSteckverbindungen()[port][1])); + } + + /** + * init Methode zur Erstellung der Einträge und Action Listener für die einzelnen Menüs + * + * @param button : Button für die die Einträge erstellt werden sollen + */ + private void menu(MenuButton button, String[] str) { + mItem = new ArrayList<>(); + for (int i = 0; i < str.length; i++) { + //Eintrag aus str der Arraylist mi hinzufügen + mItem.add(new MenuItem(str[i])); + //MenuItem mi dem Button button hinzufügen + button.getItems().add(mItem.get(i)); + int finalI = i; + //Listener für die einzelnen Einträge + ArrayList<MenuItem> finalMi = mItem; + mItem.get(i).setOnAction(e -> setMenuBtnText(button, finalMi.get(finalI))); + } + } + //endregion + + //region EventHandler/Listener + + /** + * Wird ausgelöst wenn der gedrückte Button losgelassen wird. + * Setzt die Hintergrundfarbe des Kreises mit dem chiffrierten Buchstaben auf grau, + * durch Aufruf der Methode leuchten. + * + * @param e => übergibt den zuletzt losgelassenen Button + */ + @FXML + void tasteRauf(MouseEvent e) { + if (e.getSource() == btnA) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnB) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnC) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnD) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnE) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnF) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnG) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnH) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnI) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnJ) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnK) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnL) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnM) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnN) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnO) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnP) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnQ) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnR) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnS) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnT) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnU) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnV) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnW) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnX) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnY) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnZ) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + } + + /** + * Wird ausgelöst sobald eine Taste gedrückt wird (beim drücken der Taste) + * Auswertung welche Buchstaben-Taste gedrückt ist. + * Übergabe des entspechenden Buchstaben als Parameter der Methode setText welche den chiffrierten Buchstaben + * in der Klassen-Variablen chiffrierterBuchstabe ablegt. + * Setzt die Hintergrundfarbe des Kreises mit dem chiffrierten Buchstaben auf gelb + * + * @param e => übergibt den momentan gedrückten Buttons + */ + @FXML + void tasteRunter(MouseEvent e) { + if (e.getSource() == btnA) { + setText(btnA); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnB) { + setText(btnB); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnC) { + setText(btnC); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnD) { + setText(btnD); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnE) { + setText(btnE); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnF) { + setText(btnF); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnG) { + setText(btnG); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnH) { + setText(btnH); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnI) { + setText(btnI); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnJ) { + setText(btnJ); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnK) { + setText(btnK); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnL) { + setText(btnL); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnM) { + setText(btnM); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnN) { + setText(btnN); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnO) { + setText(btnO); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnP) { + setText(btnP); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnQ) { + setText(btnQ); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnR) { + setText(btnR); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnS) { + setText(btnS); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnT) { + setText(btnT); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnU) { + setText(btnU); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnV) { + setText(btnV); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnW) { + setText(btnW); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnX) { + setText(btnX); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnY) { + setText(btnY); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnZ) { + setText(btnZ); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + } + + /** + * Auswertung welcher Button (senden, empfangen oder löschen) gedrückt wurde. + * Funktionsaufruf entsprechend des gedrückten Button + * + * @param e => ActionEvent des auslösenden Button + */ + @FXML + private void gedrueckteTaste(ActionEvent e) { + if (e.getSource() == btnSenden) { + if (tfCodiert.getText().equals("")) { + new Fehler().showErrorDialog("warning", "Haben Sie heute nichts zu sagen?", + "Nutzung von militärischer Infrastruktur ohne Grund ist verboten."); + } else { + sendeFunkspruch(); + } + } + if (e.getSource() == btnEmpfangen) empfangeFunkspruch(); + if (e.getSource() == btnDelete) loeschen(); + if (e.getSource() == btnReset) { + codierer.resetHardware(); + this.resetDisplay = true; + this.setzeTagesSchluessel(); + } + } + //endregion + + //region Methoden + + /** + * Setzt die Hintergrundfarbe des Kreises (chiffrierter Buchstabe) auf gelb bzw. auf grau. + * + * @param leuchte => gibt an welcher Kreis (chiffrierter Buchstabe) den Hintergrund ändern soll + * @param shiningLetter => "AN" -> setzt Hintergrundfarbe des Kreises (chiffrierter Buchstabe) auf gelb + * "AUS" -> setzt Hintergrundfarbe des Kreises (chiffrierter Buchstabe) auf grau + */ + private void leuchten(Circle leuchte, BUCHSTABE_LEUCHTET shiningLetter) { + if (shiningLetter == BUCHSTABE_LEUCHTET.AN) leuchte.setStyle("-fx-fill: #FFA500"); + else if (shiningLetter == BUCHSTABE_LEUCHTET.AUS) { + leuchte.setStyle("-fx-background-color: grey"); + leuchte.setStyle("-fx-border-color: #000000"); + } + } + + /** + * Gibt den Buchstabenkreis entsprechend des chiffrierten Buchstabens zurück + * + * @param chiffLetter => chiffrierter Buchstabe + * @return => Kreis des chiffrierten Buchstabens (der leuchten soll) + */ + private Circle chiffCircle(char chiffLetter) { + switch (chiffLetter) { + case 'A': + return circA; + case 'B': + return circB; + case 'C': + return circC; + case 'D': + return circD; + case 'E': + return circE; + case 'F': + return circF; + case 'G': + return circG; + case 'H': + return circH; + case 'I': + return circI; + case 'J': + return circJ; + case 'K': + return circK; + case 'L': + return circL; + case 'M': + return circM; + case 'N': + return circN; + case 'O': + return circO; + case 'P': + return circP; + case 'Q': + return circQ; + case 'R': + return circR; + case 'S': + return circS; + case 'T': + return circT; + case 'U': + return circU; + case 'V': + return circV; + case 'W': + return circW; + case 'X': + return circX; + case 'Y': + return circY; + case 'Z': + return circZ; + } + return null; + } + + /** + * Methode zum setzen des menuButton Textes auf das ausgewählte MenuItem + * + * @param mBtn : MenuButton der Walze + * @param mItm : MenuItem + */ + private void setMenuBtnText(MenuButton mBtn, MenuItem mItm) { + if (mBtn.getId().equals(mBtnStartPos1.getId())) setzePosition(1, mItm.getText().charAt(0)); + if (mBtn.getId().equals(mBtnStartPos2.getId())) setzePosition(2, mItm.getText().charAt(0)); + if (mBtn.getId().equals(mBtnStartPos3.getId())) setzePosition(3, mItm.getText().charAt(0)); + if (mBtn.getId().equals(mBtnWalzPos1.getId())) setzeWalze(1, mItm.getText()); + if (mBtn.getId().equals(mBtnWalzPos2.getId())) setzeWalze(2, mItm.getText()); + if (mBtn.getId().equals(mBtnWalzPos3.getId())) setzeWalze(3, mItm.getText()); + if (mBtn.getId().equals(mBtnNotchPos1.getId())) + setzeRing(1, Integer.parseInt(mItm.getText()) - 1); + if (mBtn.getId().equals(mBtnNotchPos2.getId())) + setzeRing(2, Integer.parseInt(mItm.getText()) - 1); + if (mBtn.getId().equals(mBtnNotchPos3.getId())) + setzeRing(3, Integer.parseInt(mItm.getText()) - 1); + tfCodiert.setText(""); + tfKlartext.setText(""); + } + + /** + * Hier werden die TextFelder, welche die Steckverbindungen darstellen, + * mit dem Werten die die Klasse Codierer zur Verfügung stellt gefüllt. + */ + private void setzeSteckverbindungen() { + tfStecker1.setText(codierer.fetchSteckverbindungen()[0][0] + "" + codierer.fetchSteckverbindungen()[0][1]); + tfStecker2.setText(codierer.fetchSteckverbindungen()[1][0] + "" + codierer.fetchSteckverbindungen()[1][1]); + tfStecker3.setText(codierer.fetchSteckverbindungen()[2][0] + "" + codierer.fetchSteckverbindungen()[2][1]); + tfStecker4.setText(codierer.fetchSteckverbindungen()[3][0] + "" + codierer.fetchSteckverbindungen()[3][1]); + tfStecker5.setText(codierer.fetchSteckverbindungen()[4][0] + "" + codierer.fetchSteckverbindungen()[4][1]); + tfStecker6.setText(codierer.fetchSteckverbindungen()[5][0] + "" + codierer.fetchSteckverbindungen()[5][1]); + tfStecker7.setText(codierer.fetchSteckverbindungen()[6][0] + "" + codierer.fetchSteckverbindungen()[6][1]); + tfStecker8.setText(codierer.fetchSteckverbindungen()[7][0] + "" + codierer.fetchSteckverbindungen()[7][1]); + tfStecker9.setText(codierer.fetchSteckverbindungen()[8][0] + "" + codierer.fetchSteckverbindungen()[8][1]); + tfStecker10.setText(codierer.fetchSteckverbindungen()[9][0] + "" + codierer.fetchSteckverbindungen()[9][1]); + } + + /** + * Die Löschen Funktion löscht das letzte Zeichen im Klartext sowie im Codiert Feld, + * der Codierer wird aufgerufen um ebenfalls das letzte Zeichen zu löschen + */ + private void loeschen() { + if (textEingabe.length() == 0) { + tfKlartext.setText(""); + tfCodiert.setText(""); + } else { + textEingabe = textEingabe.substring(0, textEingabe.length() - 1); + textCodiert = textCodiert.substring(0, textCodiert.length() - 1); + tfKlartext.setText(textEingabe); + tfCodiert.setText(textCodiert); + codierer.letztesZeichenLoeschen(); + mBtnStartPos1.setText(String.valueOf(this.codierer.fetchWalzen()[0])); + mBtnStartPos2.setText(String.valueOf(this.codierer.fetchWalzen()[1])); + mBtnStartPos3.setText(String.valueOf(this.codierer.fetchWalzen()[2])); + } + } + + /** + * Holt Nachricht von Klasse Codierer und setzt den chiffrierten Text in das Textfeld tfCodiert, + * sowie den Klartext in das Textfeld tfKlartext. Setzt den Spruchschlüssel + */ + private void empfangeFunkspruch() { + + progressDialogue("rx"); + + try { + if (this.empfangeneNachricht[2] != null && this.empfangeneNachricht[1] != null) { + setzeTagesSchluessel(); + tfKlartext.setText(this.empfangeneNachricht[2]); + tfCodiert.setText(this.empfangeneNachricht[1]); + resetDisplay = true; + + // Spruchschluessel in das Feld lblSpruchschluessel schreiben + lblSpruchschluessel.setText(codierer.empfangenerSpruchschluessel(this.empfangeneNachricht[2])); + } + } catch (NullPointerException ignored) { + new Fehler().showErrorDialog( + "warning", + "Keiner schreibt dir...", + "Es liegen keine neuen Nachrichten im Funkraum für Sie vor."); + } + } + + /** + * Senden der Nachricht mit Hilfe der Klasse Codierer + * Löscht die Textfelder tfKlartext und tfCodiert + */ + private void sendeFunkspruch() { + + this.tfKlartext.setText(""); + this.tfCodiert.setText(""); + + progressDialogue("tx"); + } + + private void progressDialogue(String strRxTx) { + + Task copyWorker = createWorker(strRxTx); + + ProgressDialog dialog = new ProgressDialog(copyWorker); + dialog.initStyle(StageStyle.TRANSPARENT); + dialog.setGraphic(null); + dialog.initStyle(StageStyle.TRANSPARENT); + dialog.setTitle("Kommunikation zum Funkraum"); + if (strRxTx.equals("rx")) { + dialog.setContentText("Empfange Nachricht"); + } else if (strRxTx.equals("tx")) { + dialog.setContentText("Sende Nachricht"); + } + dialog.setHeaderText(null); + dialog.setGraphic(null); + dialog.initStyle(StageStyle.UTILITY); + new Thread(copyWorker).start(); + dialog.showAndWait(); + } + + public Task createWorker(String strRxTx) { + return new Task() { + @Override + protected Object call() throws Exception { + if (strRxTx.equals("rx")) { + empfangeneNachricht = codierer.empfangeNachricht(); + } else if (strRxTx.equals("tx")) { + try { + codierer.sendeNachricht(); + } catch (HttpException | IOException e) { + e.printStackTrace(); + } + } + + return true; + } + }; + } + + /** + * Schreibt Buchstaben des gedrückten Button in Textfeld tfKlartext. + * Übergabe des Buchstaben vom gedrückten Button an die Klasse Codierer + * Ablegen des chiffrierten Buchstaben in der char Variable chiffrierterBuchstabe + * Hinzufügen des chiffrierten Buchstaben in Textfeld tfCodiert + * Aktualisierung der Walzenstellung + * + * @param pressedButton : gedrückter Knopf + */ + private void setText(Button pressedButton) { + if (textEingabe.length() < 250) { + if (this.resetDisplay) { + this.tfCodiert.setText(""); + this.tfKlartext.setText(""); + this.resetDisplay = false; + this.codierer.resetHardware(); + textCodiert = ""; + textEingabe = ""; + // Spruchschlüssel generieren und codieren + this.codierer.generateSpruchschluessel(); + // Spruchschluessel in das Feld lblSpruchschluessel schreiben + lblSpruchschluessel.setText(this.codierer.getSpruchschluessel()); + } + textEingabe += pressedButton.getText(); + chiffrierterBuchstabe = codierer.codiere(pressedButton.getText().charAt(0), true); + textCodiert += chiffrierterBuchstabe; + + tfKlartext.setText(textEingabe); + tfCodiert.setText(textCodiert); + + // Position der Walzen aktuallisieren + mBtnStartPos1.setText(String.valueOf(this.codierer.fetchWalzen()[0])); + mBtnStartPos2.setText(String.valueOf(this.codierer.fetchWalzen()[1])); + mBtnStartPos3.setText(String.valueOf(this.codierer.fetchWalzen()[2])); + } + } + + /** + * Setzt die Anzeige des entsprechende Gui-Element auf die entsprechende Walze + * ->d.h. welche Walze sitzt auf welcher Position + * + * @param walzeRoemischNr => gibt die Walzennummer an + * @param walzenPosition => gibt die Position der Walze + */ + private void setzeWalze(int walzenPosition, String walzeRoemischNr) { + int walzeNr = 0; + switch (walzeRoemischNr) { + case "I": + walzeNr = 0; + break; + case "II": + walzeNr = 1; + break; + case "III": + walzeNr = 2; + break; + case "IV": + walzeNr = 4; + break; + case "V": + walzeNr = 4; + break; + default: + break; + } + + switch (walzenPosition) { + case 1: + mBtnWalzPos1.setText(walzenNr[walzeNr]); + break; + case 2: + mBtnWalzPos2.setText(walzenNr[walzeNr]); + break; + case 3: + mBtnWalzPos3.setText(walzenNr[walzeNr]); + break; + default: + break; + } + } + + /** + * Setzt die Anzeige des entsprechende Gui-Element auf die entsprechende Walze + * -> d.h. welche Walze sitzt auf welcher Position + * + * @param walzenPosition => gibt die Position der Walze + * @param walzeNr => gibt die Walzennummer an + */ + private void setzeWalze(int walzenPosition, int walzeNr) { + //int walzeNr = 0; + switch (walzeNr) { + case 1: + walzeNr = 0; + break; + case 2: + walzeNr = 1; + break; + case 3: + walzeNr = 2; + break; + case 4: + walzeNr = 3; + break; + case 5: + walzeNr = 4; + break; + default: + break; + } + + switch (walzenPosition) { + case 1: + mBtnWalzPos1.setText(walzenNr[walzeNr]); + //codierer.setWalze(walzeNr, walzenPosition) + break; + case 2: + mBtnWalzPos2.setText(walzenNr[walzeNr]); + break; + case 3: + mBtnWalzPos3.setText(walzenNr[walzeNr]); + break; + default: + break; + } + } + + /** + * Setzt den Notch (position)=> die Mitnahmeposition der Walze (walze) fest + * Mitnahmeposition meint => die nächste Walze wird bei erreichen dieser Position (notch) + * um eine Stelle versetzt + * + * @param ringStellung => gibt die walze an + * @param walzenPosition => gibt den notch der Walze (walze) an + */ + private void setzeRing(int walzenPosition, int ringStellung) { + switch (walzenPosition) { + case 1: + mBtnNotchPos1.setText(ringNr[ringStellung]); + break; + case 2: + mBtnNotchPos2.setText(ringNr[ringStellung]); + break; + case 3: + mBtnNotchPos3.setText(ringNr[ringStellung]); + break; + default: + break; + } + } + + /** + * Setzt die Startposition/ aktuelle Position der Walze + * + * @param walze => gibt die walze an + * @param buchstabe gibt den Startwert bzw die aktuelle Position der Walze (walze) an + */ + private void setzePosition(int walze, char buchstabe) { + switch (walze) { + case 1: + mBtnStartPos1.setText(String.valueOf(buchstabe)); + break; + case 2: + mBtnStartPos2.setText(buchstabe + ""); + break; + case 3: + mBtnStartPos3.setText(buchstabe + ""); + break; + default: + break; + } + } + + /** + * Setzt den aktuellen TagesSchluessel und zeigt diesen in der GUI an + */ + private void setzeTagesSchluessel() { + + // Umsprungpunkte anzeigen + mBtnNotchPos1.setText(String.valueOf(codierer.fetchRingstellung()[0])); + mBtnNotchPos2.setText(String.valueOf(codierer.fetchRingstellung()[1])); + mBtnNotchPos3.setText(String.valueOf(codierer.fetchRingstellung()[2])); + + // Walzennummern anzeigen + setzeWalze(1, codierer.fetchWalzenNr()[0]); + setzeWalze(2, codierer.fetchWalzenNr()[1]); + setzeWalze(3, codierer.fetchWalzenNr()[2]); + + // Position der Walzen anzeigen + mBtnStartPos1.setText(String.valueOf(codierer.fetchWalzen()[0])); + mBtnStartPos2.setText(String.valueOf(codierer.fetchWalzen()[1])); + mBtnStartPos3.setText(String.valueOf(codierer.fetchWalzen()[2])); + + // Steckbrett Felder setzen + + // Setzt das Steckbrett + generateSteckbrett(); + + /* + tfStecker1.setText(codierer.fetchSteckverbindungen()[0][0] + "" + + codierer.fetchSteckverbindungen()[0][1]); + tfStecker2.setText(codierer.fetchSteckverbindungen()[1][0] + "" + + codierer.fetchSteckverbindungen()[1][1]); + tfStecker3.setText(codierer.fetchSteckverbindungen()[2][0] + "" + + codierer.fetchSteckverbindungen()[2][1]); + tfStecker4.setText(codierer.fetchSteckverbindungen()[3][0] + "" + + codierer.fetchSteckverbindungen()[3][1]); + tfStecker5.setText(codierer.fetchSteckverbindungen()[4][0] + "" + + codierer.fetchSteckverbindungen()[4][1]); + tfStecker6.setText(codierer.fetchSteckverbindungen()[5][0] + "" + + codierer.fetchSteckverbindungen()[5][1]); + tfStecker7.setText(codierer.fetchSteckverbindungen()[6][0] + "" + + codierer.fetchSteckverbindungen()[6][1]); + tfStecker8.setText(codierer.fetchSteckverbindungen()[7][0] + "" + + codierer.fetchSteckverbindungen()[7][1]); + tfStecker9.setText(codierer.fetchSteckverbindungen()[8][0] + "" + + codierer.fetchSteckverbindungen()[8][1]); + tfStecker10.setText(codierer.fetchSteckverbindungen()[9][0] + "" + + codierer.fetchSteckverbindungen()[9][1]);*/ + this.textCodiert = ""; + this.textEingabe = ""; + this.tfKlartext.setText(""); + this.tfCodiert.setText(""); + } + + private enum BUCHSTABE_LEUCHTET {AN, AUS} + + public void setKenngruppe(String kenngruppe) { + + // Initialisieren des Codierers und setzen der Kenngruppe + codierer = new Codierer(kenngruppe); + + this.codierer.resetHardware(); + + // Beim nächsten Tastendruck erstmal das Display löschen damit falschen Nachrichten geschickt werden. + resetDisplay = true; + + // Einstellungen aus dem Logbuch auslesen und setzen + setzeTagesSchluessel(); + setzeSteckverbindungen(); + } + //endregion } diff --git a/src/main/java/projekt/enigma/KenngruppeController.java b/src/main/java/projekt/enigma/KenngruppeController.java deleted file mode 100644 index 714cc678814f83bc46c2b81ba1f82eb97d49e8d0..0000000000000000000000000000000000000000 --- a/src/main/java/projekt/enigma/KenngruppeController.java +++ /dev/null @@ -1,44 +0,0 @@ -package projekt.enigma; - -import java.io.IOException; - -import javafx.fxml.FXML; -import javafx.scene.control.TextField; -import projekt.enigma.model.Codierer; - -public class KenngruppeController { - private Codierer cod = new Codierer(); - - @FXML - private TextField tfKenngruppe; - - //TODO: Doku - - /** - * Beim drücken der Taste wird überprüft ob die eingegebene Kenngruppe weniger als 9 Zeichen hat und ob die - * eingegebenen Zeichen nur Buchstaben sind. - * Bei einer gültigen Eingabe wird die eingegebene Kenngruppe gespeichert und die Enigma-Anwendung gestartet - * - * @throws IOException : - */ - @FXML - private void btnGui() throws IOException { - - String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - boolean error = false; - - for (char c : tfKenngruppe.getText().toUpperCase().toCharArray()) { - if (!alphabet.contains(String.valueOf(c))) { - error = true; - } - } - if (tfKenngruppe.getText().length() < 9 && !error) { - cod.setKenngruppe(tfKenngruppe.getText().toUpperCase()); - //setzt - App.setRoot("gui"); - } else { - tfKenngruppe.setStyle("-fx-background-color:#FF0000"); - tfKenngruppe.setText("Fehlerhafte Kenngruppe!"); - } - } -} diff --git a/src/main/java/projekt/enigma/Main.java b/src/main/java/projekt/enigma/Main.java index ec28c8326559cd7f825ec1b94e8263a36f93adb6..b5abaf5e0ca620dbe5c06670a79b78aa1ee41db4 100644 --- a/src/main/java/projekt/enigma/Main.java +++ b/src/main/java/projekt/enigma/Main.java @@ -9,10 +9,6 @@ import java.sql.SQLException; public class Main { public static void main(String[] args) throws SQLException { - Thread app = new Thread(new ThreadApp()); - Thread funk = new Thread(new ThreadFunkraum()); - - app.start(); - funk.start(); + App.main(args); } } diff --git a/src/main/java/projekt/enigma/model/Codierer.java b/src/main/java/projekt/enigma/model/Codierer.java index 33789a373f29fab20960043f7890ea8551040ad2..ce401e31527f9a557c8b505c0ed3cc7b8b6a67c9 100644 --- a/src/main/java/projekt/enigma/model/Codierer.java +++ b/src/main/java/projekt/enigma/model/Codierer.java @@ -45,6 +45,9 @@ public class Codierer { * Im Codebuch sind die Tageswerte zu finden. Über dieses Objekt kann darauf zugegriffen werden. */ private Codebuch codebuch; + + //TODO Dokumentieren + private Thread funk; //endregion //region Konstruktor @@ -53,12 +56,13 @@ public class Codierer { * Der Konstruktor des Codierers * Hier werden die globalen Variablen auf ihre Standart Werte gesetzt sowie die Objekte Initialisiert. */ - public Codierer() { + public Codierer(String kenngruppe) { this.nachricht = ""; this.spruchschluessel = ""; this.spruchschluesselCodiert = ""; - this.kenngruppe = ""; + this.kenngruppe = kenngruppe; + this.codebuch = new Codebuch(); this.codebuch.fetchTagesschluessel(); } @@ -156,7 +160,7 @@ public class Codierer { String[] codierteNachricht = new Funkraum().empfangeFunkspruch(this.kenngruppe); // Prüfen ob Nachrichtenlänge > 1 und die codierte Nachricht mehr als drei Felder (" ") hat - if (codierteNachricht.length > 1 && codierteNachricht[1].split(" ").length > 3) { + if (codierteNachricht[1] != null && codierteNachricht[1].split(" ").length > 3) { // Den Tag der Nachricht speichern nachricht[0] = codierteNachricht[0]; // Die Nachricht von Morsecode in Buchstaben konvertieren @@ -177,10 +181,6 @@ public class Codierer { } } nachricht[1] = sb.toString(); - } else { - nachricht[0] = ""; - nachricht[1] = ""; - nachricht[2] = "Es liegen keine neuen Nachrichten im Funkraum für Sie vor."; } return nachricht; @@ -342,6 +342,16 @@ public class Codierer { return walzen; } + + /** + * TODO: Doku + * + * @param port + * @return + */ + public String fetchVerfuegbareBuchstaben(int port) { + return this.hardware.getSteckbrett().fetchVerfuegbareBuchstaben(port); + } //endregion //region codierer @@ -488,12 +498,14 @@ public class Codierer { //region Setter /** - * Gibt die bisher erstellte Nachricht zurück + * Setzt die Kenngruppe welche die Enigma gerade benutzt. * - * @return String : Erstellte Nachricht + * @param kenngruppe : String : Kenngruppe welche die Enigma gerade benutzt */ - public String getNachricht() { - return nachricht; + public void setKenngruppe(String kenngruppe) { + + this.kenngruppe = kenngruppe; + this.initialisiereHardware(); } //endregion @@ -509,18 +521,6 @@ public class Codierer { return kenngruppe; } - /** - * Setzt die Kenngruppe welche die Enigma gerade benutzt. - * - * @param kenngruppe : String : Kenngruppe welche die Enigma gerade benutzt - */ - public void setKenngruppe(String kenngruppe) { - - this.kenngruppe = kenngruppe; - this.initialisiereHardware(); - - } - /** * Der Spruchschlüssel wird, zur internen Verwendung, auch im Klartext gespeichert. * Wir brauchen diesen dann zum codieren der eigentlichen Nachricht. @@ -530,5 +530,14 @@ public class Codierer { public String getSpruchschluessel() { return this.spruchschluessel; } + + /** + * Gibt die bisher erstellte Nachricht zurück + * + * @return String : Erstellte Nachricht + */ + public String getNachricht() { + return nachricht; + } //endregion } diff --git a/src/main/java/projekt/enigma/model/Fehler.java b/src/main/java/projekt/enigma/model/Fehler.java new file mode 100644 index 0000000000000000000000000000000000000000..2617b700baed9a77d9b3c5a249649dd20f7aaf05 --- /dev/null +++ b/src/main/java/projekt/enigma/model/Fehler.java @@ -0,0 +1,78 @@ +package projekt.enigma.model; + +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; +import projekt.enigma.App; + +/** + * In dieser Klasse werden Fehler behandelt und an den User/Admin/Entwickler ausgegeben + */ +public class Fehler { + + private String functionPrefix = "- "; + private String messagePrefix = "--> "; + + /** + * Zeige Fehler Dialog + * + * @param type : String : Art der Meldung (warning/information/error) + * @param subject : Titel des Dialoges + * @param message : Nachricht der Meldung + */ + public void showErrorDialog(String type, String subject, String message) { + + new Fehler().debug(this.getClass().getName() + "." + new Throwable().getStackTrace()[0].getMethodName(), true); + + Alert alert; + + /* Der Titel darf auch als leerer String übergeben werden, dann wird ein Default gesetzt */ + if (subject.equals("")) { + subject = "Es ist ein Fehler aufgetreten"; + } + + /* Welcher Fehler Typ wurde übergeben? */ + switch (type) { + case "warning": + alert = new Alert(AlertType.WARNING); + break; + case "info": + alert = new Alert(AlertType.INFORMATION); + break; + case "error": + alert = new Alert(AlertType.ERROR); + break; + default: + alert = new Alert(AlertType.NONE); + } + /* Setzt den Titel des Dialoges */ + alert.setTitle(subject); + /* Setzt den Headertext des Dialoges */ + alert.setHeaderText(null); + /* Setzt die Nachricht des Dialoges */ + alert.setContentText(message); + /* Zeige den Dialog an */ + alert.showAndWait(); + } + + public void debug(String message, boolean isFunction) { + + if (App.getDebug() != 0) { + if (isFunction) { + System.out.println(functionPrefix + message); + } else { + System.out.println(messagePrefix + message); + } + } + } + + public void debug(String message, boolean isFunction, int debugLevel) { + + if (App.getDebug() != 0 && (App.getDebug() >= debugLevel || App.getDebug() == 3)) { + if (isFunction) { + System.out.println(functionPrefix + message); + } else { + System.out.println(messagePrefix + message); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/projekt/enigma/model/Funkraum.java b/src/main/java/projekt/enigma/model/Funkraum.java index f596cfad8ef16c6e1479e798fb1123afc5cb8da6..3310b32c5a145e4adadcb6fa73314b1d7f6731f6 100644 --- a/src/main/java/projekt/enigma/model/Funkraum.java +++ b/src/main/java/projekt/enigma/model/Funkraum.java @@ -63,10 +63,14 @@ public class Funkraum { } } } catch (UnsupportedEncodingException e) { - System.out.println("Encoding wird nicht unterstützt."); + new Fehler().showErrorDialog("error", "Encoding wird nicht unterstützt", + "Kommunikation mit dem Feind wird als Landesverrat bestraft"); } catch (IOException e) { - System.out.println("HTTP Post war nicht erfolgreich.\nBitte wenden Sie sich an ihren Vorgesetzten."); - e.printStackTrace(); + new Fehler().showErrorDialog("error", "HTTP Post war nicht erfolgreich", + "Bitte wenden Sie sich an ihren Vorgesetzten."); + } catch (NullPointerException e) { + new Fehler().showErrorDialog("info", "Keiner schreibt dir...", + "Es liegen keine neuen Nachrichten im Funkraum für Sie vor."); } return funkspruch; @@ -106,8 +110,9 @@ public class Funkraum { BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent())); JSONObject result = new JSONObject(reader.readLine()); if (result.getInt("result") != 200) { - throw new HttpException("Der andere Funker mag deine Nachricht nicht. " + - "Rüge ihn wenn du ihn wieder siehst..."); + new Fehler().showErrorDialog("error", "HTTP Exception", + "Der andere Funker mag deine Nachricht nicht. " + + "Rüge ihn wenn du ihn wieder siehst..."); } } } diff --git a/src/main/java/projekt/enigma/model/Hardware.java b/src/main/java/projekt/enigma/model/Hardware.java index 290f8c4951774533d1a7db8c0ed8fb603ad2ae79..f188a2c935d9c0f622502e1bd92a18a99a293727 100644 --- a/src/main/java/projekt/enigma/model/Hardware.java +++ b/src/main/java/projekt/enigma/model/Hardware.java @@ -15,177 +15,199 @@ package projekt.enigma.model; */ public class Hardware { - //region Variablen - /** - * TODO: Dokumentieren - */ - private Walze[] walzen; - private Steckbrett steckbrett; - private Reflektor reflektor; - //endregion - - //region Konstruktor - /** - * Im Konstruktor legen wir die Anzahl der Walzen fest welche die Hardware aufnehmen kann. - * Die Enigma I welche hier nachgebildet werden soll, konnte drei Walzen aufnehmen. - */ - public Hardware() { - this.walzen = new Walze[3]; - } - //endregion - - //region Funktionen & Methoden - /** - * Setzt eine Walze ein - * - * @param walze : int : Setzt die Walze mit der angegebenen Nummer ein - * @param walzenNr : int : Die Nummer der einzusetzenden Walze - */ - public void setzeWalzenNr(int walze, int walzenNr, int ringstellung) { - this.walzen[walze] = new Walze(walzenNr, ringstellung); - } - - /** - * Setzt den Notch der Walze - * - * @param walze : int : Position der Walze - * @param position : int : Umspringpunkt auf der Walze - */ - public void setzeRing(int walze, int position) { - this.walzen[walze].setRingstellung(position); - } - - /** - * Setzt den Startwert (position) der Walze (walze) - * - * @param walze : int : Nummer der Walze - * @param buchstabe : char : Buchstabe der zugewiesen soll - */ - public void setzePosition(int walze, char buchstabe) { - this.walzen[walze].setPosition(buchstabe); - } - - /** - * Verschlüsselt den übergebenen Buchstaben und fügt ihn der Nachricht hinzu - * - * @param buchstabe char : Der zu ver/entschlüsselnde Buchstabe - * @return char : Der ver/entschlüsselte Buchstabe - */ - public char codiere(char buchstabe) { - - buchstabe = Character.toUpperCase(buchstabe); - this.dreheWalzen(1); - - buchstabe = this.steckbrett.codiere(Character.toUpperCase(buchstabe)); - buchstabe = this.walzen[2].codiere(buchstabe); - buchstabe = this.walzen[1].codiere(buchstabe); - buchstabe = this.walzen[0].codiere(buchstabe); - buchstabe = this.reflektor.codiere(buchstabe); - buchstabe = this.walzen[0].codiere2(buchstabe); - buchstabe = this.walzen[1].codiere2(buchstabe); - buchstabe = this.walzen[2].codiere2(buchstabe); - buchstabe = this.steckbrett.codiere(buchstabe); - - return buchstabe; - } - - /** - * Nach jeder codierung eines Buchstabens müssen die Walzen gedreht werden. - * Hier überprüfen wir welche der Walzen gedreht werden müssen und stoßen die Vorgang an. - */ - public void dreheWalzen(int richtung) { - if (richtung > 0) { - for (int i = 0; i < richtung; i++) { - if (this.walzen[2].dreheWalze(1)) { - if(this.walzen[1].dreheWalze(1)) { - this.walzen[0].dreheWalze(1); - } - } - } - } else { - for (int i = 0; i > richtung; richtung++) { - if (this.walzen[2].dreheWalze(-1)) { - if(this.walzen[1].dreheWalze(-1)) { - this.walzen[0].dreheWalze(-1); - } - } - } - } - } - - /** - * Diese Funktion setzt die Walzen auf ihren Anfangswert zurück. - * Hierfür ist der Buchstabe "A" festgelegt. - * Dies wird benötigt um zB einen neuen Spruchschlüssel einzustellen oder eine neue Nachricht zu verfassen. - */ - public void resetWalzen() { - this.getWalzen()[0].setPosition('A'); - this.getWalzen()[1].setPosition('A'); - this.getWalzen()[2].setPosition('A'); - } - //endregion - - //region Setter - /** - * Setzt eine Walze ein und speichert das Objekt im Walzen Array - * - * @param position : int : Position der Walze - * @param walze : int : Die Nummer der Walze - * @param ringstellung : int : Umsprung Punkt der Walze - */ - public void setWalzen(int position, int walze, int ringstellung) { - this.walzen[position] = new Walze(walze, ringstellung); - } - - /** - * Setzt den Reflektor ein. - * In der Enigma I welche hier nachgebaut wird, gab es nur einen Reflektor. - * Spätere Versionen haten zwei oder mehr, deshalb haben wir hier auch schon ein Objekt dafür erstellt, - * welches ausgetauscht werden kann. - * - * @param reflektor : Reflektor : Das Obejtk des Reflektors - */ - public void setReflektor(Reflektor reflektor) { - this.reflektor = reflektor; - } - - /** - * Setzt das übergebene Steckbrett Objekt in die Hardware ein - * - * @param steckbrett : Steckbrett : Objekt des Steckbretts mit allen verbundenen Kabeln - */ - public void setSteckbrett(Steckbrett steckbrett) { - this.steckbrett = steckbrett; - } - //endregion - - //region Getter - /** - * Gibt das Objekt des Steckbretts zurück - * - * @return Steckbrett : Das eingesetzte Steckbrett mit seinen Kabeln wenn eingesteckt - */ - public Steckbrett getSteckbrett() { - return steckbrett; - } - - /** - * Liest den Reflektor aus und gibt ihn zurück - * - * @return Reflektor : Objekt des Reflektors - */ - public Reflektor getReflektor() { - return reflektor; - } - - /** - * Gibt die verbauten Walzen Objekte zurück - * - * @return Walze[] : Array mit den Walzen Objekten - */ - public Walze[] getWalzen() { - return this.walzen; - } - //endregion + //region Variablen + /** + * TODO: Dokumentieren + */ + private Walze[] walzen; + private Steckbrett steckbrett; + private Reflektor reflektor; + //endregion + + //region Konstruktor + + /** + * Im Konstruktor legen wir die Anzahl der Walzen fest welche die Hardware aufnehmen kann. + * Die Enigma I welche hier nachgebildet werden soll, konnte drei Walzen aufnehmen. + */ + public Hardware() { + this.walzen = new Walze[3]; + } + //endregion + + //region Funktionen & Methoden + + /** + * Setzt eine Walze ein + * + * @param walze : int : Setzt die Walze mit der angegebenen Nummer ein + * @param walzenNr : int : Die Nummer der einzusetzenden Walze + */ + public void setzeWalzenNr(int walze, int walzenNr, int ringstellung) { + this.walzen[walze] = new Walze(walzenNr, ringstellung); + } + + /** + * Setzt den Notch der Walze + * + * @param walze : int : Position der Walze + * @param position : int : Umspringpunkt auf der Walze + */ + public void setzeRing(int walze, int position) { + this.walzen[walze].setRingstellung(position); + } + + /** + * Setzt den Startwert (position) der Walze (walze) + * + * @param walze : int : Nummer der Walze + * @param buchstabe : char : Buchstabe der zugewiesen soll + */ + public void setzePosition(int walze, char buchstabe) { + this.walzen[walze].setPosition(buchstabe); + } + + /** + * Verschlüsselt den übergebenen Buchstaben und fügt ihn der Nachricht hinzu + * + * @param buchstabe char : Der zu ver/entschlüsselnde Buchstabe + * @return char : Der ver/entschlüsselte Buchstabe + */ + public char codiere(char buchstabe) { + + new Fehler().debug(this.getClass().getName() + "." + + new Throwable().getStackTrace()[0].getMethodName(), true); + buchstabe = Character.toUpperCase(buchstabe); + String debug = String.format("Positionen: W1:%s W2:%s W3:%s", + this.walzen[0].getPosition(), + this.walzen[1].getPosition(), + this.walzen[2].getPosition()); + debug += "\nI\tS\t3\t2\t1\tR\t1\t2\t3\tS\n" + buchstabe; + + this.dreheWalzen(1); + + buchstabe = this.steckbrett.codiere(Character.toUpperCase(buchstabe)); + debug += "\t" + buchstabe; + buchstabe = this.walzen[2].codiere(buchstabe); + debug += "\t" + buchstabe; + buchstabe = this.walzen[1].codiere(buchstabe); + debug += "\t" + buchstabe; + buchstabe = this.walzen[0].codiere(buchstabe); + debug += "\t" + buchstabe; + buchstabe = this.reflektor.codiere(buchstabe); + debug += "\t" + buchstabe; + buchstabe = this.walzen[0].codiere2(buchstabe); + debug += "\t" + buchstabe; + buchstabe = this.walzen[1].codiere2(buchstabe); + debug += "\t" + buchstabe; + buchstabe = this.walzen[2].codiere2(buchstabe); + debug += "\t" + buchstabe; + buchstabe = this.steckbrett.codiere(buchstabe); + debug += "\t" + buchstabe; + new Fehler().debug(debug, false); + + return buchstabe; + } + + /** + * Nach jeder codierung eines Buchstabens müssen die Walzen gedreht werden. + * Hier überprüfen wir welche der Walzen gedreht werden müssen und stoßen die Vorgang an. + */ + public void dreheWalzen(int richtung) { + if (richtung > 0) { + for (int i = 0; i < richtung; i++) { + if (this.walzen[2].dreheWalze(1)) { + if (this.walzen[1].dreheWalze(1)) { + this.walzen[0].dreheWalze(1); + } + } + } + } else { + for (int i = 0; i > richtung; richtung++) { + if (this.walzen[2].dreheWalze(-1)) { + if (this.walzen[1].dreheWalze(-1)) { + this.walzen[0].dreheWalze(-1); + } + } + } + } + } + + /** + * Diese Funktion setzt die Walzen auf ihren Anfangswert zurück. + * Hierfür ist der Buchstabe "A" festgelegt. + * Dies wird benötigt um zB einen neuen Spruchschlüssel einzustellen oder eine neue Nachricht zu verfassen. + */ + public void resetWalzen() { + this.getWalzen()[0].setPosition('A'); + this.getWalzen()[1].setPosition('A'); + this.getWalzen()[2].setPosition('A'); + } + //endregion + + //region Setter + + /** + * Setzt eine Walze ein und speichert das Objekt im Walzen Array + * + * @param position : int : Position der Walze + * @param walze : int : Die Nummer der Walze + * @param ringstellung : int : Umsprung Punkt der Walze + */ + public void setWalzen(int position, int walze, int ringstellung) { + this.walzen[position] = new Walze(walze, ringstellung); + } + + /** + * Gibt das Objekt des Steckbretts zurück + * + * @return Steckbrett : Das eingesetzte Steckbrett mit seinen Kabeln wenn eingesteckt + */ + public Steckbrett getSteckbrett() { + return steckbrett; + } + + /** + * Setzt das übergebene Steckbrett Objekt in die Hardware ein + * + * @param steckbrett : Steckbrett : Objekt des Steckbretts mit allen verbundenen Kabeln + */ + public void setSteckbrett(Steckbrett steckbrett) { + this.steckbrett = steckbrett; + } + //endregion + + //region Getter + + /** + * Liest den Reflektor aus und gibt ihn zurück + * + * @return Reflektor : Objekt des Reflektors + */ + public Reflektor getReflektor() { + return reflektor; + } + + /** + * Setzt den Reflektor ein. + * In der Enigma I welche hier nachgebaut wird, gab es nur einen Reflektor. + * Spätere Versionen haten zwei oder mehr, deshalb haben wir hier auch schon ein Objekt dafür erstellt, + * welches ausgetauscht werden kann. + * + * @param reflektor : Reflektor : Das Obejtk des Reflektors + */ + public void setReflektor(Reflektor reflektor) { + this.reflektor = reflektor; + } + + /** + * Gibt die verbauten Walzen Objekte zurück + * + * @return Walze[] : Array mit den Walzen Objekten + */ + public Walze[] getWalzen() { + return this.walzen; + } + //endregion } diff --git a/src/main/java/projekt/enigma/model/Steckbrett.java b/src/main/java/projekt/enigma/model/Steckbrett.java index b2d698f7b576b685230f97dd524b8e7767e60147..426424bac13c717a37c9b7529a39d71436ea033e 100644 --- a/src/main/java/projekt/enigma/model/Steckbrett.java +++ b/src/main/java/projekt/enigma/model/Steckbrett.java @@ -132,4 +132,27 @@ public class Steckbrett { } } + /** + * TODO: Doku + * @param port + * @return + */ + public String fetchVerfuegbareBuchstaben(int port) { + + String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + for (char c : this.originalBuchstaben.toCharArray()) { + alphabet = alphabet.replace(String.valueOf(c), ""); + } + + for (char c : this.getauschteBuchstaben.toCharArray()) { + alphabet = alphabet.replace(String.valueOf(c), ""); + } + + alphabet += originalBuchstaben.charAt(port); + alphabet += getauschteBuchstaben.charAt(port); + + return alphabet; + } + } \ No newline at end of file diff --git a/src/main/java/projekt/enigma/threads/ThreadFunkraum.java b/src/main/java/projekt/enigma/threads/ThreadFunkraum.java index 786f57c7beeeba4bf4b1e13fbefe3ae4b25d564f..de29d542844c7821056d85b39cdc646ce3dd1f70 100644 --- a/src/main/java/projekt/enigma/threads/ThreadFunkraum.java +++ b/src/main/java/projekt/enigma/threads/ThreadFunkraum.java @@ -7,7 +7,11 @@ import projekt.enigma.model.Funkraum; * Thread fuer den Funkraum, wird durch das Interface Runnable erweitert */ public class ThreadFunkraum implements Runnable { - String kenngruppe = new Codierer().getKenngruppe(); + String kenngruppe; + + public ThreadFunkraum(String kenngruppe) { + this.kenngruppe = kenngruppe; + } /** * Ueberschriebene Funktion - fuehrt die Klasse Funkraum aus und startet die Methode empfangeFunkspruch @@ -16,7 +20,7 @@ public class ThreadFunkraum implements Runnable { public void run() { Funkraum funkraum = new Funkraum(); System.out.println("Threadfunkraum" + Thread.currentThread()); - funkraum.empfangeFunkspruch(kenngruppe); + funkraum.empfangeFunkspruch(this.kenngruppe); } } diff --git a/src/main/resources/projekt/enigma/gui.fxml b/src/main/resources/projekt/enigma/gui.fxml index 541232d5cffb09e2bcd7a2c7d5a910faed867ba6..e1f89f7b45830201cfc80800a7eff6bcffcec0f3 100644 --- a/src/main/resources/projekt/enigma/gui.fxml +++ b/src/main/resources/projekt/enigma/gui.fxml @@ -8,11 +8,12 @@ <?import javafx.scene.layout.AnchorPane?> <?import javafx.scene.layout.ColumnConstraints?> <?import javafx.scene.layout.GridPane?> +<?import javafx.scene.layout.Pane?> <?import javafx.scene.layout.RowConstraints?> <?import javafx.scene.shape.Circle?> <?import javafx.scene.text.Font?> -<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="677.0" prefWidth="962.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="projekt.enigma.GuiController"> +<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="677.0" prefWidth="962.0" xmlns="http://javafx.com/javafx/8.0.999-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="projekt.enigma.GuiController"> <children> <AnchorPane layoutX="207.0" layoutY="-111.0" prefHeight="111.0" prefWidth="487.0" AnchorPane.leftAnchor="207.0" AnchorPane.rightAnchor="274.0" /> <GridPane layoutX="23.0" layoutY="60.0" prefHeight="158.0" prefWidth="237.0" AnchorPane.leftAnchor="23.0" AnchorPane.topAnchor="60.0"> @@ -97,7 +98,7 @@ <Button fx:id="btnReset" mnemonicParsing="false" onAction="#gedrueckteTaste" text="Zurücksetzen" GridPane.rowIndex="1" /> </children> </GridPane> - <GridPane layoutX="6.0" layoutY="294.0" prefHeight="377.0" prefWidth="952.0" AnchorPane.bottomAnchor="6.0" AnchorPane.leftAnchor="6.0" AnchorPane.rightAnchor="9.0" AnchorPane.topAnchor="294.0"> + <GridPane fx:id="mainGrid" layoutX="6.0" layoutY="294.0" prefHeight="377.0" prefWidth="952.0" AnchorPane.bottomAnchor="6.0" AnchorPane.leftAnchor="6.0" AnchorPane.rightAnchor="9.0" AnchorPane.topAnchor="294.0"> <columnConstraints> <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> @@ -669,6 +670,7 @@ <Insets left="42.0" /> </GridPane.margin> </Label> + <Pane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="7" /> </children> </GridPane> <Label layoutX="684.0" layoutY="-164.0" prefHeight="17.0" prefWidth="195.0" />