From 134cd4c8c83614c48608e926c336e3e5f9a44e06 Mon Sep 17 00:00:00 2001
From: blueShard-dev <63594396+blueShard-dev@users.noreply.github.com>
Date: Mon, 4 May 2020 21:23:29 +0200
Subject: [PATCH] Add files via upload

---
 src/META-INF/MANIFEST.MF                      |    3 +
 src/org/blueshard/cryptogx/Config.java        |  789 ++++++++
 src/org/blueshard/cryptogx/Controller.java    | 1581 +++++++++++++++++
 src/org/blueshard/cryptogx/EnDecrypt.java     |  531 ++++++
 src/org/blueshard/cryptogx/Main.java          |  269 +++
 src/org/blueshard/cryptogx/SecureDelete.java  |  196 ++
 src/org/blueshard/cryptogx/Utils.java         |   21 +
 .../cryptogx/resources/addSettingsGUI.fxml    |   91 +
 .../blueshard/cryptogx/resources/close.png    |  Bin 0 -> 14702 bytes
 .../blueshard/cryptogx/resources/cryptoGX.png |  Bin 0 -> 51400 bytes
 .../cryptogx/resources/exportSettingsGUI.fxml |   28 +
 .../cryptogx/resources/loadSettingsGUI.fxml   |   26 +
 .../blueshard/cryptogx/resources/loading.gif  |  Bin 0 -> 9270 bytes
 .../blueshard/cryptogx/resources/mainGUI.fxml |  103 ++
 .../blueshard/cryptogx/resources/minimize.png |  Bin 0 -> 14698 bytes
 15 files changed, 3638 insertions(+)
 create mode 100644 src/META-INF/MANIFEST.MF
 create mode 100644 src/org/blueshard/cryptogx/Config.java
 create mode 100644 src/org/blueshard/cryptogx/Controller.java
 create mode 100644 src/org/blueshard/cryptogx/EnDecrypt.java
 create mode 100644 src/org/blueshard/cryptogx/Main.java
 create mode 100644 src/org/blueshard/cryptogx/SecureDelete.java
 create mode 100644 src/org/blueshard/cryptogx/Utils.java
 create mode 100644 src/org/blueshard/cryptogx/resources/addSettingsGUI.fxml
 create mode 100644 src/org/blueshard/cryptogx/resources/close.png
 create mode 100644 src/org/blueshard/cryptogx/resources/cryptoGX.png
 create mode 100644 src/org/blueshard/cryptogx/resources/exportSettingsGUI.fxml
 create mode 100644 src/org/blueshard/cryptogx/resources/loadSettingsGUI.fxml
 create mode 100644 src/org/blueshard/cryptogx/resources/loading.gif
 create mode 100644 src/org/blueshard/cryptogx/resources/mainGUI.fxml
 create mode 100644 src/org/blueshard/cryptogx/resources/minimize.png

diff --git a/src/META-INF/MANIFEST.MF b/src/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..76191f1
--- /dev/null
+++ b/src/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: org.blueshard.cryptogx.Main
+
diff --git a/src/org/blueshard/cryptogx/Config.java b/src/org/blueshard/cryptogx/Config.java
new file mode 100644
index 0000000..f11f65e
--- /dev/null
+++ b/src/org/blueshard/cryptogx/Config.java
@@ -0,0 +1,789 @@
+package org.blueshard.cryptogx;
+
+import javafx.application.Platform;
+import javafx.collections.FXCollections;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.*;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.KeyCode;
+import javafx.scene.layout.AnchorPane;
+import javafx.scene.layout.VBox;
+import javafx.stage.*;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.xml.stream.*;
+import javax.xml.transform.*;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+import java.io.*;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicReference;
+
+import static org.blueshard.cryptogx.Main.*;
+
+/**
+ * <p>Class for the user configuration / settings</p>
+ */
+public class Config {
+
+    private static double addConfigGUIX, addConfigGUIY;
+
+    private static final HashSet<String> protectedConfigNames = new HashSet<>(Arrays.asList("cryptoGX", "config"));
+
+    /**
+     * <p>Shows a GUI where the user can save settings, which can load later</p>
+     *
+     * @param rootWindow from which this GUI will get called
+     * @param userSetting
+     * @throws IOException
+     */
+    public static void addSettingGUI(Window rootWindow, Map<String, String> userSetting) throws IOException {
+        Map<String, String> newSettingItems = new HashMap<>();
+
+        Stage rootStage = new Stage();
+        rootStage.initOwner(rootWindow);
+        Parent addSettingsRoot = FXMLLoader.load(Config.class.getResource("resources/addSettingsGUI.fxml"));
+        rootStage.initStyle(StageStyle.UNDECORATED);
+        rootStage.initModality(Modality.WINDOW_MODAL);
+        rootStage.setResizable(false);
+        rootStage.setTitle("cryptoGX");
+        Scene scene = new Scene(addSettingsRoot, 320, 605);
+
+        rootStage.setScene(scene);
+
+        scene.setOnMouseDragged(event -> {
+            rootStage.setX(event.getScreenX() + addConfigGUIX);
+            rootStage.setY(event.getScreenY() + addConfigGUIY);
+        });
+        scene.setOnMousePressed(event -> {
+            addConfigGUIX = scene.getX() - event.getSceneX();
+            addConfigGUIY = scene.getY() - event.getSceneY();
+        });
+
+        Thread thread = new Thread(() -> {
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+
+            Platform.runLater(() -> {
+                MenuBar menuBar = (MenuBar) addSettingsRoot.lookup("#menuBar");
+                menuBar.setOnMouseDragged(event -> {
+                    rootStage.setX(event.getScreenX() + addConfigGUIX);
+                    rootStage.setY(event.getScreenY() + addConfigGUIY);
+                });
+                menuBar.setOnMousePressed(event -> {
+                    addConfigGUIX = menuBar.getLayoutX() - event.getSceneX();
+                    addConfigGUIY = menuBar.getLayoutY() - event.getSceneY();
+                });
+
+                ImageView closeButton = (ImageView) addSettingsRoot.lookup("#closeButton");
+                closeButton.setOnMouseClicked(event -> rootStage.close());
+
+                TextField settingsNameEntry = (TextField) addSettingsRoot.lookup("#settingsNameEntry");
+
+                TextField textKeyEntry = (TextField) addSettingsRoot.lookup("#textKeyEntry");
+                textKeyEntry.setText(userSetting.get("textKey"));
+                TextField textSaltEntry = (TextField) addSettingsRoot.lookup("#textSaltEntry");
+                textSaltEntry.setText(userSetting.get("textSalt"));
+                ComboBox textAlgorithmBox = (ComboBox) addSettingsRoot.lookup("#textAlgorithmComboBox");
+                textAlgorithmBox.setItems(FXCollections.observableArrayList(textAlgorithms));
+                textAlgorithmBox.setValue(userSetting.get("textAlgorithm"));
+
+                TextField fileEnDecryptKeyEntry = (TextField) addSettingsRoot.lookup("#fileEnDecryptKeyEntry");
+                fileEnDecryptKeyEntry.setText(userSetting.get("fileEnDecryptKey"));
+                TextField fileEnDecryptSaltEntry = (TextField) addSettingsRoot.lookup("#fileEnDecryptSaltEntry");
+                fileEnDecryptSaltEntry.setText(userSetting.get("fileEnDecryptSalt"));
+                ComboBox fileEnDecryptAlgorithmBox = (ComboBox) addSettingsRoot.lookup("#fileEnDecryptAlgorithmComboBox");
+                fileEnDecryptAlgorithmBox.setItems(FXCollections.observableArrayList(fileEnDecryptAlgorithms));
+                fileEnDecryptAlgorithmBox.setValue(userSetting.get("fileEnDecryptAlgorithm"));
+
+                TextField fileDeleteIterationEntry = (TextField) addSettingsRoot.lookup("#fileDeleteIterationsEntry");
+                fileDeleteIterationEntry.setText(userSetting.get("fileDeleteIterations"));
+                fileDeleteIterationEntry.textProperty().addListener((observable, oldValue, newValue) -> {
+                    if (!newValue.matches("[0-9]*")) {
+                        fileDeleteIterationEntry.setText(oldValue);
+                    }
+                });
+
+                TextField fileOutputPathEntry = (TextField) addSettingsRoot.lookup("#fileOutputPathEntry");
+                fileOutputPathEntry.setText(userSetting.get("fileOutputPath"));
+                CheckBox removeFromFileBoxCheckBox = (CheckBox) addSettingsRoot.lookup("#removeFromFileBoxCheckBox");
+                removeFromFileBoxCheckBox.setSelected(Boolean.parseBoolean(userSetting.get("removeFromFileBox")));
+                CheckBox limitNumberOfThreadsCheckBox = (CheckBox) addSettingsRoot.lookup("#limitNumberOfThreadsCheckBox");
+                limitNumberOfThreadsCheckBox.setSelected(Boolean.parseBoolean(userSetting.get("limitNumberOfThreads")));
+
+                PasswordField hiddenPasswordEntry = (PasswordField) addSettingsRoot.lookup("#hiddenPasswordEntry");
+                TextField showedPasswordEntry = (TextField) addSettingsRoot.lookup("#showedPasswordEntry");
+                CheckBox showPassword = (CheckBox) addSettingsRoot.lookup("#showPassword");
+
+                showPassword.setOnAction(event -> {
+                    if (showPassword.isSelected()) {
+                        showedPasswordEntry.setText(hiddenPasswordEntry.getText());
+                        showedPasswordEntry.setVisible(true);
+                        hiddenPasswordEntry.setVisible(false);
+                    } else {
+                        hiddenPasswordEntry.setText(showedPasswordEntry.getText());
+                        hiddenPasswordEntry.setVisible(true);
+                        showedPasswordEntry.setVisible(false);
+                    }
+                });
+                CheckBox encryptSettings = (CheckBox) addSettingsRoot.lookup("#encryptSettings");
+                encryptSettings.setOnAction(event -> {
+                    if (encryptSettings.isSelected()) {
+                        hiddenPasswordEntry.setDisable(false);
+                        showedPasswordEntry.setDisable(false);
+                        showPassword.setDisable(false);
+                    } else {
+                        hiddenPasswordEntry.setDisable(true);
+                        showedPasswordEntry.setDisable(true);
+                        showPassword.setDisable(true);
+                    }
+                });
+                Button saveButton = (Button) addSettingsRoot.lookup("#saveButton");
+                saveButton.setOnAction(event -> {
+                    if (settingsNameEntry.getText().trim().isEmpty()) {
+                        warningAlert("Add a name for the setting");
+                    } else if (protectedConfigNames.contains(settingsNameEntry.getText())) {
+                        warningAlert("Please choose another name for this setting");
+                    } else if (encryptSettings.isSelected()){
+                        try {
+                            EnDecrypt.AES encrypt;
+                            if (!hiddenPasswordEntry.isDisabled()) {
+                                encrypt = new EnDecrypt.AES(hiddenPasswordEntry.getText(), new byte[16]);
+                                newSettingItems.put("encryptHash", encrypt.encrypt(hiddenPasswordEntry.getText()));
+                            } else {
+                                encrypt = new EnDecrypt.AES(showedPasswordEntry.getText(), new byte[16]);
+                                newSettingItems.put("encryptHash", encrypt.encrypt(showedPasswordEntry.getText()));
+                            }
+
+                            newSettingItems.put("textKey", encrypt.encrypt(textKeyEntry.getText()));
+                            newSettingItems.put("textSalt", encrypt.encrypt(textSaltEntry.getText()));
+                            newSettingItems.put("textAlgorithm", encrypt.encrypt(textAlgorithmBox.getSelectionModel().getSelectedItem().toString()));
+
+                            newSettingItems.put("fileEnDecryptKey", encrypt.encrypt(fileEnDecryptKeyEntry.getText()));
+                            newSettingItems.put("fileEnDecryptSalt", encrypt.encrypt(fileEnDecryptSaltEntry.getText()));
+                            newSettingItems.put("fileEnDecryptAlgorithm", encrypt.encrypt(fileEnDecryptAlgorithmBox.getSelectionModel().getSelectedItem().toString()));
+
+                            newSettingItems.put("fileDeleteIterations", encrypt.encrypt(fileDeleteIterationEntry.getText()));
+
+                            newSettingItems.put("fileOutputPath", encrypt.encrypt(fileOutputPathEntry.getText()));
+                            newSettingItems.put("removeFromFileBox", encrypt.encrypt(String.valueOf(removeFromFileBoxCheckBox.isSelected())));
+                            newSettingItems.put("limitNumberOfThreads", encrypt.encrypt(String.valueOf(limitNumberOfThreadsCheckBox.isSelected())));
+
+                            addSetting(settingsNameEntry.getText(), newSettingItems);
+
+                            rootStage.close();
+                        } catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | InvalidKeySpecException e) {
+                            e.printStackTrace();
+                        }
+                    } else {
+                        newSettingItems.put("encryptHash", "");
+
+                        newSettingItems.put("textKey", textKeyEntry.getText());
+                        newSettingItems.put("textSalt", textSaltEntry.getText());
+                        newSettingItems.put("textAlgorithm", textAlgorithmBox.getSelectionModel().getSelectedItem().toString());
+
+                        newSettingItems.put("fileEnDecryptKey", fileEnDecryptKeyEntry.getText());
+                        newSettingItems.put("fileEnDecryptSalt", fileEnDecryptSaltEntry.getText());
+                        newSettingItems.put("fileEnDecryptAlgorithm", fileEnDecryptAlgorithmBox.getSelectionModel().getSelectedItem().toString());
+
+                        newSettingItems.put("fileDeleteIterations", fileDeleteIterationEntry.getText());
+
+                        newSettingItems.put("fileOutputPath", fileOutputPathEntry.getText());
+                        newSettingItems.put("removeFromFileBox", String.valueOf(removeFromFileBoxCheckBox.isSelected()));
+                        newSettingItems.put("limitNumberOfThreads", String.valueOf(limitNumberOfThreadsCheckBox.isSelected()));
+
+                        addSetting(settingsNameEntry.getText(), newSettingItems);
+
+                        rootStage.close();
+                    }
+                });
+            });
+        });
+
+        thread.start();
+
+        rootStage.showAndWait();
+    }
+
+    /**
+     * <p>Shows a GUI where the user can export settings to a extra file</p>
+     *
+     * @param rootWindow from which this GUI will get called
+     * @throws IOException
+     */
+    public static void exportSettingsGUI(Window rootWindow) throws IOException {
+        Stage rootStage = new Stage();
+        rootStage.initOwner(rootWindow);
+        Parent exportSettingsRoot = FXMLLoader.load(Config.class.getResource("resources/exportSettingsGUI.fxml"));
+        rootStage.initStyle(StageStyle.UNDECORATED);
+        rootStage.initModality(Modality.WINDOW_MODAL);
+        rootStage.setResizable(false);
+        rootStage.setTitle("cryptoGX");
+        Scene scene = new Scene(exportSettingsRoot, 254, 253);
+
+        rootStage.setScene(scene);
+
+        scene.setOnMouseDragged(event -> {
+            rootStage.setX(event.getScreenX() + addConfigGUIX);
+            rootStage.setY(event.getScreenY() + addConfigGUIY);
+        });
+        scene.setOnMousePressed(event -> {
+            addConfigGUIX = scene.getX() - event.getSceneX();
+            addConfigGUIY = scene.getY() - event.getSceneY();
+        });
+
+        Thread thread = new Thread(() -> {
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+            MenuBar menuBar = (MenuBar) exportSettingsRoot.lookup("#menuBar");
+            menuBar.setOnMouseDragged(event -> {
+                rootStage.setX(event.getScreenX() + addConfigGUIX);
+                rootStage.setY(event.getScreenY() + addConfigGUIY);
+            });
+            menuBar.setOnMousePressed(event -> {
+                addConfigGUIX = menuBar.getLayoutX() - event.getSceneX();
+                addConfigGUIY = menuBar.getLayoutY() - event.getSceneY();
+            });
+            ImageView closeButton = (ImageView) exportSettingsRoot.lookup("#closeButton");
+            closeButton.setOnMouseClicked(event -> rootStage.close());
+
+            VBox settingsBox = (VBox) exportSettingsRoot.lookup("#settingsBox");
+            Platform.runLater(() -> readUserSettings().keySet().forEach(s -> {
+                CheckBox newCheckBox = new CheckBox();
+                newCheckBox.setText(s);
+                settingsBox.getChildren().add(newCheckBox);
+            }));
+
+            Button exportButton = (Button) exportSettingsRoot.lookup("#exportButton");
+            exportButton.setOnAction(event -> {
+                FileChooser fileChooser = new FileChooser();
+                fileChooser.setTitle("Export settings");
+                fileChooser.setInitialFileName("settings.config");
+                fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("Config files", "*.config", "*.xml"),
+                        new FileChooser.ExtensionFilter("All files", "*.*"));
+                File file = fileChooser.showSaveDialog(exportSettingsRoot.getScene().getWindow());
+                if (file != null) {
+                    TreeMap<String, Map<String, String>> writeInfos = new TreeMap<>();
+                    TreeMap<String, Map<String, String>> settings = readUserSettings();
+                    for (int i=0; i<settingsBox.getChildren().size(); i++) {
+                        CheckBox checkBox = (CheckBox) settingsBox.getChildren().get(i);
+                        if (checkBox.isSelected()) {
+                            String checkBoxText = checkBox.getText();
+                            writeInfos.put(checkBoxText, settings.get(checkBoxText));
+                        }
+                    }
+                    if (!file.getAbsolutePath().contains(".")) {
+                        file = new File(file.getAbsolutePath() + ".config");
+                    }
+                    writeConfig(file, writeInfos);
+                }
+            });
+        });
+
+        thread.start();
+
+        rootStage.showAndWait();
+    }
+
+    /**
+     * <p>Shows a GUI where the user can load saved settings</p>
+     *
+     * @param rootWindow from which this GUI will get called
+     * @return the settings that the user has chosen
+     * @throws IOException
+     */
+    public static TreeMap<String, Map<String, String>> loadSettingsGUI(Window rootWindow) throws IOException {
+        Button[] outerLoadButton = new Button[1];
+        HashMap<String, String> setting = new HashMap<>();
+        TreeMap<String, Map<String, String>> settingItems = readUserSettings();
+        TreeMap<String, Map<String, String>> returnItems = new TreeMap<>();
+
+        Stage rootStage = new Stage();
+        rootStage.initOwner(rootWindow);
+        AnchorPane loadSettingsRoot = FXMLLoader.load(Config.class.getResource("resources/loadSettingsGUI.fxml"));
+        rootStage.initStyle(StageStyle.UNDECORATED);
+        rootStage.initModality(Modality.WINDOW_MODAL);
+        rootStage.setResizable(false);
+        rootStage.setTitle("cryptoGX");
+        rootStage.getIcons().add(new Image(Config.class.getResource("resources/cryptoGX.png").toExternalForm()));
+        Scene scene = new Scene(loadSettingsRoot, 242, 235);
+
+        scene.setOnMouseDragged(event -> {
+            rootStage.setX(event.getScreenX() + addConfigGUIX);
+            rootStage.setY(event.getScreenY() + addConfigGUIY);
+        });
+        scene.setOnMousePressed(event -> {
+            addConfigGUIX = scene.getX() - event.getSceneX();
+            addConfigGUIY = scene.getY() - event.getSceneY();
+        });
+
+        scene.setOnKeyReleased(event -> {
+            if (event.getCode() == KeyCode.ENTER) {
+                outerLoadButton[0].fire();
+            }
+        });
+
+        Thread thread = new Thread(() -> {
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+            Platform.runLater(() -> {
+                MenuBar menuBar = (MenuBar) loadSettingsRoot.lookup("#menuBar");
+                menuBar.setOnMouseDragged(event -> {
+                    rootStage.setX(event.getScreenX() + addConfigGUIX);
+                    rootStage.setY(event.getScreenY() + addConfigGUIY);
+                });
+                menuBar.setOnMousePressed(event -> {
+                    addConfigGUIX = menuBar.getLayoutX() - event.getSceneX();
+                    addConfigGUIY = menuBar.getLayoutY() - event.getSceneY();
+                });
+
+                ImageView closeButton = (ImageView) loadSettingsRoot.lookup("#closeButton");
+                if (settingItems.isEmpty()) {
+                    rootStage.close();
+                }
+
+                closeButton.setOnMouseClicked(event -> {
+                    setting.put("encryptHash", configDefaultEncryptHash);
+
+                    setting.put("textKey", configDefaultTextKey);
+                    setting.put("textSalt", configDefaultTextSalt);
+                    setting.put("textAlgorithm", configDefaultTextAlgorithm);
+
+                    setting.put("fileEnDecryptKey", configDefaultFileEnDecryptKey);
+                    setting.put("fileEnDecryptSalt", configDefaultFileEnDecryptSalt);
+                    setting.put("fileEnDecryptAlgorithm", configDefaultFileEnDecryptAlgorithm);
+
+                    setting.put("fileDeleteIterations", String.valueOf(configDefaultFileDeleteIterations));
+
+                    setting.put("fileOutputPath", configDefaultFileOutputPath);
+                    setting.put("removeFromFileBox", String.valueOf(configDefaultRemoveFileFromFileBox));
+                    setting.put("limitNumberOfThreads", String.valueOf(configDefaultLimitNumberOfThreads));
+
+                    returnItems.put("default", setting);
+
+                    rootStage.close();
+                });
+
+                PasswordField keyHideEntry = (PasswordField) loadSettingsRoot.lookup("#passwordEntryHide");
+                TextField keyShowEntry = (TextField) loadSettingsRoot.lookup("#passwordEntryShow");
+
+                CheckBox showPassword = (CheckBox) loadSettingsRoot.lookup("#showPassword");
+                showPassword.setOnAction(event -> {
+                    if (showPassword.isSelected()) {
+                        keyShowEntry.setText(keyHideEntry.getText());
+                        keyShowEntry.setVisible(true);
+                        keyHideEntry.setVisible(false);
+                    } else {
+                        keyHideEntry.setText(keyShowEntry.getText());
+                        keyHideEntry.setVisible(true);
+                        keyShowEntry.setVisible(false);
+                    }
+                });
+
+                ComboBox settingsBox = (ComboBox) loadSettingsRoot.lookup("#settingsBox");
+                settingsBox.setItems(FXCollections.observableArrayList(settingItems.keySet()));
+                settingsBox.setValue(settingItems.firstKey());
+                if (settingItems.firstEntry().getValue().get("encryptHash").trim().isEmpty()) {
+                    keyHideEntry.clear();
+                    keyHideEntry.setDisable(true);
+                    keyShowEntry.setDisable(true);
+                    showPassword.setDisable(true);
+                }
+                settingsBox.setOnAction(event -> {
+                    try {
+                        if (settingItems.get(settingsBox.getSelectionModel().getSelectedItem().toString()).get("encryptHash").trim().isEmpty()) {
+                            keyHideEntry.clear();
+                            keyHideEntry.setDisable(true);
+                            keyShowEntry.clear();
+                            keyShowEntry.setDisable(true);
+                            showPassword.setDisable(true);
+                        } else {
+                            keyHideEntry.clear();
+                            keyHideEntry.setDisable(false);
+                            keyShowEntry.clear();
+                            keyShowEntry.setDisable(false);
+                            showPassword.setDisable(false);
+                        }
+                    } catch (NullPointerException e) {
+                        //get called when delete button is pressed
+                    }
+                });
+
+                Button loadButton = (Button) loadSettingsRoot.lookup("#loadButton");
+                loadButton.setOnAction(event -> {
+                    String settingName = settingsBox.getSelectionModel().getSelectedItem().toString();
+                    Map<String, String> selectedSetting = settingItems.get(settingName);
+                    if (keyHideEntry.isDisabled() && showPassword.isDisabled() && showPassword.isDisabled()) {
+                        setting.put("encryptHash", "");
+
+                        setting.put("textKey", selectedSetting.get("textKey"));
+                        setting.put("textSalt", selectedSetting.get("textSalt"));
+                        setting.put("textAlgorithm", selectedSetting.get("textAlgorithm"));
+
+                        setting.put("fileEnDecryptKey", selectedSetting.get("fileEnDecryptKey"));
+                        setting.put("fileEnDecryptSalt", selectedSetting.get("fileEnDecryptSalt"));
+                        setting.put("fileEnDecryptAlgorithm", selectedSetting.get("fileEnDecryptAlgorithm"));
+
+                        setting.put("fileDeleteIterations", selectedSetting.get("fileDeleteIterations"));
+
+                        setting.put("fileOutputPath", selectedSetting.get("fileOutputPath"));
+                        setting.put("removeFromFileBox", selectedSetting.get("removeFromFileBox"));
+                        setting.put("limitNumberOfThreads", selectedSetting.get("limitNumberOfThreads"));
+
+                        returnItems.put(settingsBox.getSelectionModel().getSelectedItem().toString(), setting);
+
+                        rootStage.close();
+                    } else {
+                        EnDecrypt.AES decryptSetting;
+                        if (keyHideEntry.isVisible()) {
+                            decryptSetting = new EnDecrypt.AES(keyHideEntry.getText(), new byte[16]);
+                        } else {
+                            decryptSetting = new EnDecrypt.AES(keyShowEntry.getText(), new byte[16]);
+                        }
+                        try {
+                            if (keyHideEntry.isVisible() && !decryptSetting.encrypt(keyHideEntry.getText()).equals(settingItems.get(settingsBox.getSelectionModel().getSelectedItem().toString()).get("encryptHash").trim())) {
+                                warningAlert("Wrong key is given");
+                            } else if (keyShowEntry.isVisible() && !decryptSetting.encrypt(keyShowEntry.getText()).equals(settingItems.get(settingsBox.getSelectionModel().getSelectedItem().toString()).get("encryptHash").trim())) {
+                                warningAlert("Wrong key is given");
+                            } else {
+                                Map<String, String> selectedEncryptedSetting = settingItems.get(settingName);
+                                setting.put("textKey", decryptSetting.decrypt(selectedEncryptedSetting.get("textKey")));
+                                setting.put("textSalt", decryptSetting.decrypt(selectedEncryptedSetting.get("textSalt")));
+                                setting.put("textAlgorithm", decryptSetting.decrypt(selectedEncryptedSetting.get("textAlgorithm")));
+
+                                setting.put("fileEnDecryptKey", decryptSetting.decrypt(selectedEncryptedSetting.get("fileEnDecryptKey")));
+                                setting.put("fileEnDecryptSalt", decryptSetting.decrypt(selectedEncryptedSetting.get("fileEnDecryptSalt")));
+                                setting.put("fileEnDecryptAlgorithm", decryptSetting.decrypt(selectedEncryptedSetting.get("fileEnDecryptAlgorithm")));
+
+                                setting.put("fileDeleteIterations", String.valueOf(Integer.parseInt(decryptSetting.decrypt(selectedEncryptedSetting.get("fileDeleteIterations")))));
+
+                                setting.put("fileOutputPath", decryptSetting.decrypt(selectedEncryptedSetting.get("fileOutputPath")));
+                                setting.put("removeFromFileBox", decryptSetting.decrypt(selectedEncryptedSetting.get("removeFromFileBox")));
+                                setting.put("limitNumberOfThreads", decryptSetting.decrypt(selectedEncryptedSetting.get("limitNumberOfThreads")));
+
+                                returnItems.put(settingsBox.getSelectionModel().getSelectedItem().toString(), setting);
+
+                                rootStage.close();
+                            }
+                        } catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | InvalidKeySpecException e) {
+                            e.printStackTrace();
+                            warningAlert("Wrong key is given");
+                        }
+                    }
+                });
+                outerLoadButton[0] = loadButton;
+
+                Button deleteButton = (Button) loadSettingsRoot.lookup("#deleteButton");
+                deleteButton.setOnAction(event -> {
+                    AtomicReference<Double> deleteQuestionX = new AtomicReference<>((double) 0);
+                    AtomicReference<Double> deleteQuestionY = new AtomicReference<>((double) 0);
+                    Alert deleteQuestion = new Alert(Alert.AlertType.CONFIRMATION, "Delete " + settingsBox.getSelectionModel().getSelectedItem().toString() + "?", ButtonType.OK, ButtonType.CANCEL);
+                    deleteQuestion.initStyle(StageStyle.UNDECORATED);
+                    deleteQuestion.setTitle("Confirmation");
+                    ((Stage) deleteQuestion.getDialogPane().getScene().getWindow()).getIcons().add(new Image(Config.class.getResource("resources/cryptoGX.png").toExternalForm()));
+
+                    Scene window = deleteQuestion.getDialogPane().getScene();
+
+                    window.setOnMouseDragged(dragEvent -> {
+                        deleteQuestion.setX(dragEvent.getScreenX() + deleteQuestionX.get());
+                        deleteQuestion.setY(dragEvent.getScreenY() + deleteQuestionY.get());
+                    });
+                    window.setOnMousePressed(pressEvent -> {
+                        deleteQuestionX.set(window.getX() - pressEvent.getSceneX());
+                        deleteQuestionY.set(window.getY() - pressEvent.getSceneY());
+                    });
+
+                    Optional<ButtonType> result = deleteQuestion.showAndWait();
+                    if (result.get() == ButtonType.OK) {
+                        deleteUserSetting(settingsBox.getSelectionModel().getSelectedItem().toString());
+                        settingItems.clear();
+                        settingItems.putAll(readUserSettings());
+                        if (settingItems.size() == 0) {
+                            for (int i=0; i<100; i++) {
+                                if (config.isFile()) {
+                                    if (config.delete()) {
+                                        isConfig = false;
+                                        rootStage.close();
+                                        break;
+                                    }
+                                }
+                            }
+                            rootStage.close();
+                            return;
+                        }
+                        settingsBox.setItems(FXCollections.observableArrayList(settingItems.keySet()));
+                        settingsBox.setValue(settingItems.firstKey());
+                    }
+                });
+            });
+        });
+
+        thread.start();
+
+        rootStage.setScene(scene);
+        rootStage.showAndWait();
+
+        return returnItems;
+    }
+
+    /**
+     * <p>Shows a GUI where the user can save the current settings</p>
+     *
+     * @param settingName name of the new setting
+     * @param userSetting the current settings
+     */
+    public static void addSetting(String settingName, Map<String, String> userSetting) {
+        TreeMap<String, Map<String, String>> newConfig = new TreeMap<>(readUserSettings());
+        newConfig.put(settingName, userSetting);
+        writeConfig(newConfig);
+    }
+
+    /**
+     * <p>Shows a GUI where the user can save the current settings</p>
+     *
+     * @param settingName name of the new setting
+     * @param userSetting the current settings
+     * @param encryptPassword to encrypt the settings
+     */
+    public static void addSetting(String settingName, Map<String, String> userSetting, String encryptPassword) {
+        TreeMap<String, Map<String, String>> newConfig = new TreeMap<>(readUserSettings());
+        newConfig.put(settingName, userSetting);
+        writeConfig(newConfig, Collections.singletonMap(settingName, encryptPassword));
+    }
+
+    /**
+     * <p>Deletes a saved setting</p>
+     *
+     * @param name of the setting
+     * @return if the setting could be found
+     */
+    public static boolean deleteUserSetting(String name) {
+        TreeMap<String, Map<String, String>> newSetting = new TreeMap<>();
+        TreeMap<String, Map<String, String>> oldSetting = readUserSettings();
+        boolean found = false;
+
+        for (Map.Entry<String, Map<String, String>> entry: oldSetting.entrySet()) {
+            if (!entry.getKey().equals(name)) {
+                newSetting.put(entry.getKey(), entry.getValue());
+            } else {
+                found = true;
+            }
+        }
+        writeConfig(newSetting);
+        return found;
+    }
+
+    public static TreeMap<String, Map<String, String>> readUserSettings() {
+        return readUserSettings(config);
+    }
+
+    /**
+     * @see Config#readUserSettings(String)
+     */
+    public static TreeMap<String, Map<String, String>> readUserSettings(File file) {
+        TreeMap<String, Map<String, String>> rootInfos = new TreeMap<>();
+        try {
+            XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();
+            XMLStreamReader xmlStreamReader;
+            try {
+                xmlStreamReader = xmlInputFactory.createXMLStreamReader(new FileInputStream(file));
+            } catch (FileNotFoundException e) {
+                return rootInfos;
+            }
+
+            HashMap<String, String> infos = new HashMap<>();
+
+            String infoName = null;
+            StringBuilder infoCharacters = new StringBuilder();
+            String rootName = null;
+
+            while (xmlStreamReader.hasNext()) {
+
+                int eventType = xmlStreamReader.next();
+
+                switch (eventType) {
+                    case XMLStreamReader.START_ELEMENT:
+                        String startTag = xmlStreamReader.getLocalName().trim();
+                        if (startTag != null) {
+                            if (protectedConfigNames.contains(startTag)) {
+                                continue;
+                            } else if (rootName == null) {
+                                rootName = startTag;
+                            } else {
+                                infoName = startTag;
+                            }
+                        }
+                        break;
+                    case XMLStreamReader.CHARACTERS:
+                        if (infoName != null) {
+                            if (!xmlStreamReader.getText().trim().equals("")) {
+                                infoCharacters.append(xmlStreamReader.getText());
+                            }
+                        }
+                        break;
+                    case XMLStreamReader.END_ELEMENT:
+                        String endTag = xmlStreamReader.getLocalName().trim();
+                        if (endTag != null) {
+                            if (protectedConfigNames.contains(endTag)) {
+                                continue;
+                            } else if (endTag.equals(rootName)) {
+                                rootInfos.put(rootName, infos);
+                                rootName = null;
+                                infos = new HashMap<>();
+                                infoCharacters = new StringBuilder();
+                            } else {
+                                infos.put(infoName, infoCharacters.toString());
+                                infoName = null;
+                                infoCharacters = new StringBuilder();
+                            }
+                        }
+                        break;
+                }
+            }
+            xmlStreamReader.close();
+        } catch (XMLStreamException e) {
+            e.printStackTrace();
+        }
+        System.out.println(rootInfos);
+
+        return rootInfos;
+    }
+
+    /**
+     * <p>Shows a GUI where the user can choose and load saved settings </p>
+     *
+     * @param filename of the file with the settings
+     * @return the setting that the user has chosen
+     */
+    public static TreeMap<String, Map<String, String>> readUserSettings(String filename) {
+        return readUserSettings(new File(filename));
+    }
+
+    /**
+     * <p>Writes settings (could be more than one) to the pre-defined config file</p>
+     *
+     * @see Config#writeConfig(File, TreeMap, Map)
+     */
+    public static void writeConfig(TreeMap<String, Map<String, String>> userSettings) {
+        writeConfig(config, userSettings, null);
+    }
+
+    /**
+     * <p>Writes settings (could be more than one) to the pre-defined config file</p>
+     *
+     * @see Config#writeConfig(File, TreeMap, Map)
+     */
+    public static void writeConfig(TreeMap<String, Map<String, String>> userSettings, Map<String, String> encryptedSettings) {
+        writeConfig(config, userSettings, encryptedSettings);
+    }
+
+    /**
+     * <p>Writes settings (could be more than one) to the pre-defined config file</p>
+     *
+     * @see Config#writeConfig(String, TreeMap, Map)
+     */
+    public static void writeConfig(String filename, TreeMap<String, Map<String, String>> userSettings) {
+        writeConfig(filename, userSettings, null);
+    }
+
+    /**
+     * <p>Writes settings (could be more than one) to the pre-defined config file</p>
+     *
+     * @see Config#writeConfig(File, TreeMap, Map)
+     */
+    public static void writeConfig(File file, TreeMap<String, Map<String, String>> userSettings) {
+        writeConfig(file, userSettings, null);
+    }
+
+    /**
+     * <p>Writes settings (could be more than one) to a file</p>
+     *
+     * @see Config#writeConfig(String, TreeMap, Map)
+     */
+    public static void writeConfig(String filename, TreeMap<String, Map<String, String>> userSettings, Map<String, String> encryptedSettings) {
+        writeConfig(new File(filename), userSettings, encryptedSettings);
+    }
+
+    /**
+     * <p>Writes settings (could be more than one) to a file</p>
+     *
+     * @param file where the settings should be written in
+     * @param userSettings of the user
+     * @param encryptedSettings says which settings from {@param userSettings} should be encrypted with a password
+     */
+    public static void writeConfig(File file, TreeMap<String, Map<String, String>> userSettings, Map<String, String> encryptedSettings) {
+        EnDecrypt.AES encryptSetting;
+        StringWriter stringWriter = new StringWriter();
+
+        if (encryptedSettings == null) {
+            encryptedSettings = new HashMap<>();
+        }
+
+        try {
+            XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance();
+            XMLStreamWriter xmlStreamWriter = xmlOutputFactory.createXMLStreamWriter(stringWriter);
+
+            xmlStreamWriter.writeStartDocument();
+            xmlStreamWriter.writeStartElement("cryptoGX");
+            for (Map.Entry<String, Map<String, String>> settingElement: userSettings.entrySet()) {
+                xmlStreamWriter.writeStartElement(settingElement.getKey());
+                if (encryptedSettings.containsKey(settingElement.getKey())) {
+                    encryptSetting = new EnDecrypt.AES(settingElement.getKey(), new byte[16]);
+                    for (Map.Entry<String, String> entry: settingElement.getValue().entrySet()) {
+                        xmlStreamWriter.writeStartElement(entry.getKey());
+                        xmlStreamWriter.writeCharacters(encryptSetting.encrypt(entry.getValue()));
+                        xmlStreamWriter.writeEndElement();
+                    }
+                } else {
+                    for (Map.Entry<String, String> entry: settingElement.getValue().entrySet()) {
+                        xmlStreamWriter.writeStartElement(entry.getKey());
+                        xmlStreamWriter.writeCharacters(entry.getValue());
+                        xmlStreamWriter.writeEndElement();
+                    }
+                }
+                xmlStreamWriter.writeEndElement();
+            }
+            xmlStreamWriter.writeEndElement();
+            xmlStreamWriter.writeEndDocument();
+
+            //prettify
+
+            Source xmlInput = new StreamSource(new StringReader(stringWriter.toString()));
+            StringWriter prettifyStringWriter = new StringWriter();
+            StreamResult xmlOutput = new StreamResult(prettifyStringWriter);
+            TransformerFactory transformerFactory = TransformerFactory.newInstance();
+            transformerFactory.setAttribute("indent-number", 2);
+            Transformer transformer = transformerFactory.newTransformer();
+            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+            transformer.transform(xmlInput, xmlOutput);
+
+            BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file));
+            for (String s: prettifyStringWriter.getBuffer().toString().split(System.lineSeparator())) {
+                bufferedWriter.write(s);
+                bufferedWriter.newLine();
+            }
+            bufferedWriter.close();
+        } catch (XMLStreamException | IOException | NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | InvalidKeySpecException | TransformerException e) {
+            e.printStackTrace();
+        }
+    }
+
+}
diff --git a/src/org/blueshard/cryptogx/Controller.java b/src/org/blueshard/cryptogx/Controller.java
new file mode 100644
index 0000000..2b6c493
--- /dev/null
+++ b/src/org/blueshard/cryptogx/Controller.java
@@ -0,0 +1,1581 @@
+package org.blueshard.cryptogx;
+
+import javafx.application.Platform;
+import javafx.collections.FXCollections;
+import javafx.event.Event;
+import javafx.fxml.Initializable;
+import javafx.scene.Node;
+import javafx.scene.Scene;
+import javafx.scene.control.*;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.control.Menu;
+import javafx.scene.control.MenuBar;
+import javafx.scene.control.MenuItem;
+import javafx.scene.control.ScrollPane;
+import javafx.scene.control.TextArea;
+import javafx.scene.control.TextField;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.*;
+import javafx.scene.layout.AnchorPane;
+import javafx.scene.layout.VBox;
+import javafx.stage.*;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import java.net.*;
+import java.nio.charset.StandardCharsets;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+import java.util.*;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.blueshard.cryptogx.Config.*;
+import static org.blueshard.cryptogx.Main.*;
+
+public class Controller implements Initializable {
+
+    private Event fileEnDecryptLabelEvent;
+
+    private double menubarX, menubarY;
+    private boolean textLoading = false;
+    private boolean fileEnDecryptLoading = false;
+    private boolean fileDeleteLoading = false;
+    private AtomicInteger textThreads = new AtomicInteger(0);
+    private AtomicInteger totalThreads = new AtomicInteger(0);
+    private int tooltipShow = 15;
+    private final int DATAFILEURL = 2;
+    private final int FILEFILEURL = 1;
+    private final int NONSPECIFICFILEURL = 0;
+    private final int IMAGE = 78345;
+    private final int FILE = 23902;
+    private final int UNKNOWN = 12345;
+    private final KeyCombination paste = new KeyCodeCombination(KeyCode.V, KeyCombination.CONTROL_DOWN);
+    private final Image loadingImage = new Image(getClass().getResource("resources/loading.gif").toExternalForm());
+
+    private HashMap<String, String> currentConfigSettings = new HashMap<>();
+
+    private HashMap<Label, ArrayList<File>> enDecryptInputOutputFiles = new HashMap<>();
+    private HashMap<Label, ArrayList<Object>> enDecryptInputOutputInternetFiles = new HashMap<>();
+    private HashMap<Label, BufferedImage> enDecryptInputOutputClipboardImages = new HashMap<>();
+    private HashMap<Label, File> deleteInputFiles = new HashMap<>();
+    private List<Thread> fileEnDecryptThreads = Collections.synchronizedList(new ArrayList<>());
+    private List<Thread> fileDeleteThreads = Collections.synchronizedList(new ArrayList<>());
+
+    private ContextMenu fileEnDecryptInputContextMenu = new ContextMenu();
+    private ContextMenu fileDeleteInputContextMenu = new ContextMenu();
+    private Label choosedLabel = null;
+    private String choosedLabelType = null;
+    private MenuItem fileOutputFileChangeDest = new MenuItem("Change output file");
+    private MenuItem getChoosedLabelInputFileFolder = new MenuItem("Open source directory");
+    private MenuItem getChoosedLabelOutputFileFolder = new MenuItem("Open source directory");
+    private Tooltip tooltip = new Tooltip();
+
+    public AnchorPane rootWindow;
+
+    public Button fileEnDecryptFilesButton;
+    public Button fileDecrypt;
+    public Button fileEncrypt;
+    public Button fileEnDecryptStop;
+
+    public ComboBox<String> textAlgorithmBox;
+    public ComboBox<String> fileEnDecryptAlgorithmBox;
+
+    public ImageView minimizeWindow;
+    public ImageView closeWindow;
+    public ImageView textLoadingImage;
+    public ImageView fileEnDecryptLoadingImage;
+    public ImageView fileDeleteLoadingImage;
+
+    public Menu settingsMenu;
+
+    public MenuBar menubar;
+
+    public MenuItem setDefaultOutputPath;
+    public MenuItem saveSettings;
+    public MenuItem loadSettings;
+    public MenuItem exportSettings;
+    public MenuItem importSettings;
+
+    public RadioMenuItem removeFileFromFileBox;
+    public RadioMenuItem limitNumberOfThreads;
+
+    public ScrollPane fileEnDecryptInputScroll;
+
+    public TextArea textDecryptedEntry;
+    public TextArea textEncryptedEntry;
+
+    public TextField textKeyEntry;
+    public TextField textSaltEntry;
+    public TextField fileEnDecryptKeyEntry;
+    public TextField fileDecryptOutputFile;
+    public TextField fileEncryptOutputFile;
+    public TextField fileEnDecryptSaltEntry;
+    public TextField fileDeleteIterationsEntry;
+
+    public VBox fileEnDecryptInputFiles;
+    public VBox fileDeleteInputFiles;
+
+    //-----general-----//
+
+    /**
+     * <p>Shows a tooltip when the user type in some text in a text field, text area, etc. and the mouse is over this entry</p>
+     *
+     * @param event from which this method is called
+     */
+    public void keyTypedTooltip(KeyEvent event) {
+        String id = null;
+        String text = "";
+        try {
+            id = ((TextField) event.getSource()).getId();
+            text = ((TextField) event.getSource()).getText() + event.getCharacter();
+            tooltip.setText(text);
+        } catch (ClassCastException e) {
+            tooltip.setText(((TextArea) event.getSource()).getText() + event.getCharacter());
+        }
+        if (id != null) {
+            switch (id) {
+                case ("textKeyEntry"):
+                    currentConfigSettings.replace("textKey", text);
+                    break;
+                case ("textSaltEntry"):
+                    currentConfigSettings.replace("textSalt", text);
+                    break;
+                case ("fileEnDecryptKeyEntry"):
+                    currentConfigSettings.replace("fileEnDecryptKey", text);
+                    break;
+                case ("fileEnDecryptSaltEntry"):
+                    currentConfigSettings.replace("fileEnDecryptSalt", text);
+                    break;
+                case ("fileDeleteIterationsEntry"):
+                    currentConfigSettings.replace("fileDeleteIterations", String.valueOf(Integer.parseInt(text)));
+                    break;
+            }
+        }
+    }
+
+    /**
+     * <p>Shows a tooltip when to mouse is over a text field, text area, etc.</p>
+     *
+     * @param event from which this method is called
+     */
+    public void mouseOverEntryTooltip(MouseEvent event) {
+        try {
+            tooltip.setText(((TextField) event.getSource()).getText());
+        } catch (ClassCastException e) {
+            try {
+                tooltip.setText(((TextArea) event.getSource()).getText());
+            } catch (ClassCastException ex) {
+                tooltip.setText(((Label) event.getSource()).getText());
+            }
+        }
+        if (!tooltip.getText().trim().isEmpty()) {
+            tooltip.show(rootWindow.getScene().getWindow(), event.getScreenX(), event.getScreenY() + tooltipShow);
+        }
+    }
+
+    /**
+     * <p>Hides the tooltip if the mouse exit a text field, text area, etc.</p>
+     */
+    public void mouseExitEntryTooltip() {
+        tooltip.hide();
+    }
+
+    //-----root-----//
+
+    /**
+     * <p>Closed the application.
+     * Get called if red close button is pressed</p>
+     */
+    public void closeApplication() {
+        Stage rootStage = (Stage) rootWindow.getScene().getWindow();
+        rootStage.close();
+        System.exit(0);
+    }
+
+    /**
+     * <p>Hides the application.
+     * Get called if the green minimize button is pressed</p>
+     */
+    public void minimizeApplication() {
+        Stage rootStage = (Stage) rootWindow.getScene().getWindow();
+        rootStage.setIconified(true);
+    }
+
+    //-----text-----//
+
+    /**
+     * <p>Encrypt text in {@link Controller#textDecryptedEntry}.
+     * Get called if the text 'Encrypt' button is pressed</p>
+     */
+    public void textEncryptButton() {
+        final byte[] salt;
+        if (!textSaltEntry.getText().isEmpty()) {
+            salt = textSaltEntry.getText().getBytes(StandardCharsets.UTF_8);
+        } else {
+            salt = new byte[16];
+        }
+        if (!textLoading) {
+            textLoadingImage.setImage(loadingImage);
+        }
+        Thread textEncrypt = new Thread(() -> {
+            textThreads.getAndIncrement();
+            if (limitNumberOfThreads.isSelected()) {
+                while (totalThreads.get() >= Runtime.getRuntime().availableProcessors()) {
+                    try {
+                        Thread.sleep(100);
+                    } catch (InterruptedException e) {
+                        Thread.currentThread().stop();
+                    }
+                }
+            }
+            totalThreads.getAndIncrement();
+            EnDecrypt.AES encrypt = new EnDecrypt.AES(textKeyEntry.getText(), salt);
+            try {
+                String encryptedText = encrypt.encrypt(textDecryptedEntry.getText());
+                Platform.runLater(() -> {
+                    textEncryptedEntry.setText(encryptedText);
+                });
+            } catch (NoSuchPaddingException | InvalidKeySpecException | InvalidKeyException | NoSuchAlgorithmException | BadPaddingException e) {
+                e.printStackTrace();
+            } catch (IllegalArgumentException | IllegalBlockSizeException e) {
+                e.printStackTrace();
+                Platform.runLater(() -> errorAlert("Wrong text for encryption is given", e.getMessage()));
+            }
+            if ((textThreads.get() - 1) <= 0) {
+                textLoadingImage.setImage(null);
+                textLoading = false;
+            }
+            textThreads.getAndDecrement();
+            totalThreads.getAndDecrement();
+        });
+        textEncrypt.setDaemon(false);
+        textEncrypt.start();
+        textLoading = true;
+    }
+
+    /**
+     * <p>Decrypt text in {@link Controller#textEncryptedEntry}.
+     * Get called if the text 'Decrypt' button is pressed</p>
+     */
+    public void textDecryptButton() {
+        final byte[] salt;
+        if (!textSaltEntry.getText().isEmpty()) {
+            salt = textSaltEntry.getText().getBytes(StandardCharsets.UTF_8);
+        } else {
+            salt = new byte[16];
+        }
+        if (!textLoading) {
+            textLoadingImage.setImage(loadingImage);
+        }
+        Thread textDecrypt = new Thread(() -> {
+            textThreads.getAndIncrement();
+            if (limitNumberOfThreads.isSelected()) {
+                while (totalThreads.get() >= Runtime.getRuntime().availableProcessors()) {
+                    try {
+                        Thread.sleep(100);
+                    } catch (InterruptedException e) {
+                        Thread.currentThread().stop();
+                    }
+                }
+            }
+            totalThreads.getAndIncrement();
+            EnDecrypt.AES decrypt = new EnDecrypt.AES(textKeyEntry.getText(), salt);
+            try {
+                String DecryptedText = decrypt.decrypt(textEncryptedEntry.getText());
+                Platform.runLater(() -> {
+                    textDecryptedEntry.setText(DecryptedText);
+                });
+            } catch (NoSuchPaddingException | InvalidKeySpecException | InvalidKeyException | NoSuchAlgorithmException e) {
+                e.printStackTrace();
+            } catch (BadPaddingException e) {
+                e.printStackTrace();
+                Platform.runLater(() -> errorAlert("Wrong key and / or salt is given", e.getMessage()));
+            } catch (IllegalArgumentException | IllegalBlockSizeException e) {
+                e.printStackTrace();
+                Platform.runLater(() -> errorAlert("Wrong text for decryption is given", e.getMessage()));
+            }
+            if ((textThreads.get() - 1) <= 0) {
+                textLoading = false;
+                Platform.runLater(() -> textLoadingImage.setImage(null));
+            }
+            textThreads.getAndDecrement();
+            totalThreads.getAndDecrement();
+        });
+        textDecrypt.setDaemon(false);
+        textDecrypt.start();
+        textLoading = true;
+    }
+
+    //-----fileEnDecrypt-----//
+
+    /**
+     * <p>Synchronized method to get the list of threads which en- / decrypt files</p>
+     *
+     * @return list of en- / decryption threads
+     */
+    private synchronized List<Thread> getFileEnDecryptThreads() {
+        return fileEnDecryptThreads;
+    }
+
+    /**
+     * <p>Synchronized method to get the number of threads which en- / decrypt files</p>
+     *
+     * @return number of en- / decryption threads
+     */
+    private synchronized int getFileEnDecryptThreadsSize() {
+        return fileEnDecryptThreads.size();
+    }
+
+    /**
+     * <p>Synchronized method to add a thread to the file en- / decryption list of current running file en- / decryption threads</p>
+     *
+     * @param thread that should be added
+     */
+    private synchronized void addFileEnDecryptThread(Thread thread) {
+        fileEnDecryptThreads.add(thread);
+    }
+
+    /**
+     * <p>Synchronized method to remove a thread from the file en- / decryption list of current running file en- / decryption threads</p>
+     *
+     * @param thread that should be removed
+     */
+    private synchronized void removeFileEnDecryptThread(Thread thread) {
+        fileEnDecryptThreads.remove(thread);
+    }
+
+    /**
+     * <p>Adds a file for en- / decryption</p>
+     *
+     * @param file that should be added
+     */
+    private void fileEnDecryptAddFile(File file) {
+        for (Label l: enDecryptInputOutputFiles.keySet()) {
+            if (l.getText().equals(file.getAbsolutePath())) {
+                return;
+            }
+        }
+        Label newLabel = new Label(file.getAbsolutePath());
+        newLabel.setOnKeyTyped(this::keyTypedTooltip);
+        newLabel.setOnMouseMoved(this::mouseOverEntryTooltip);
+        newLabel.setOnMouseExited(event -> mouseExitEntryTooltip());
+        newLabel.setOnMouseClicked(event -> {
+            fileEnDecryptSelected(newLabel);
+            fileOutputFilesChangeText(newLabel, null, null);
+            fileEnDecryptLabelEvent = event;
+        });
+        newLabel.setContextMenu(fileEnDecryptInputContextMenu);
+        String fileAbsolutePath = file.getAbsolutePath();
+        String fileName = file.getName();
+
+        File encryptFile;
+        File decryptFile;
+        ArrayList<File> inputOutputList = new ArrayList<>();
+        if (currentConfigSettings.get("fileOutputPath").trim().isEmpty()) {
+            encryptFile = new File(fileAbsolutePath + ".cryptoGX");
+            while (encryptFile.isFile()) {
+                encryptFile = new File(encryptFile.getAbsolutePath() + ".cryptoGX");
+            }
+            if (fileAbsolutePath.endsWith(".cryptoGX")) {
+                decryptFile = new File(fileAbsolutePath.substring(0, fileAbsolutePath.length() - 9));
+                if (decryptFile.isFile()) {
+                    while (decryptFile.isFile()) {
+                        decryptFile = new File(decryptFile.getAbsolutePath() + ".cryptoGX");
+                    }
+                }
+            } else {
+                decryptFile = new File(fileAbsolutePath + ".cryptoGX");
+                while (decryptFile.isFile()) {
+                    decryptFile = new File(decryptFile.getAbsolutePath() + ".cryptoGX");
+                }
+            }
+        } else {
+            encryptFile = new File(currentConfigSettings.get("fileOutputPath").trim() + "/" + fileName + ".cryptoGX");
+            while (encryptFile.isFile()) {
+                encryptFile = new File(encryptFile.getAbsolutePath() + ".cryptoGX");
+            }
+            if (fileAbsolutePath.endsWith(".cryptoGX")) {
+                decryptFile = new File(currentConfigSettings.get("fileOutputPath").trim() + "/" + fileName.substring(0, fileAbsolutePath.length() - 9));
+                if (decryptFile.isFile()) {
+                    while (decryptFile.isFile()) {
+                        decryptFile = new File(decryptFile.getAbsolutePath() + ".cryptoGX");
+                    }
+                }
+            } else {
+                decryptFile = new File(currentConfigSettings.get("fileOutputPath").trim() + "/" + fileName + ".cryptoGX");
+                while (decryptFile.isFile()) {
+                    decryptFile = new File(decryptFile.getAbsolutePath() + ".cryptoGX");
+                }
+            }
+        }
+        System.out.println(encryptFile.getAbsolutePath() + ";" + decryptFile.getAbsolutePath());
+        inputOutputList.add(0, encryptFile);
+        inputOutputList.add(1, decryptFile);
+        fileEnDecryptInputFiles.getChildren().add(newLabel);
+        enDecryptInputOutputFiles.put(newLabel, inputOutputList);
+    }
+
+    /**
+     * <p>Adds an file from the internet for en- / decryption</p>
+     *
+     * @param url of the file
+     * @param fileType of the file
+     * @throws URISyntaxException
+     */
+    private void fileEnDecryptAddInternetFile(String url, int fileType) throws URISyntaxException {
+        String filename;
+        if (fileType == FILEFILEURL) {
+            filename = url.substring(url.lastIndexOf("/") + 1);
+        } else if (fileType == DATAFILEURL) {
+            filename = url.substring(5, url.indexOf("/")) + "." + url.substring(url.indexOf("/") + 1, url.indexOf(";"));
+        } else if (fileType == NONSPECIFICFILEURL) {
+            filename = "unknown" + System.nanoTime();
+        } else {
+            warningAlert("Cannot read given url '" + url + "'");
+            return;
+        }
+        for (Label l: enDecryptInputOutputInternetFiles.keySet()) {
+            if (l.getText().equals(filename)) {
+                return;
+            }
+        }
+        Label newLabel = new Label(filename);
+        newLabel.setOnKeyTyped(this::keyTypedTooltip);
+        newLabel.setOnMouseMoved(this::mouseOverEntryTooltip);
+        newLabel.setOnMouseExited(event -> mouseExitEntryTooltip());
+        newLabel.setOnMouseClicked(event -> {
+            fileEnDecryptSelected(newLabel);
+            fileOutputFilesChangeText(newLabel, null, null);
+            fileEnDecryptLabelEvent = event;
+        });
+        newLabel.setContextMenu(fileEnDecryptInputContextMenu);
+
+        File encryptFile;
+        File decryptFile;
+        ArrayList<Object> fileSpecs = new ArrayList<>();
+        ArrayList<File> inputOutputFiles = new ArrayList<>();
+        fileSpecs.add(0, fileType);
+        fileSpecs.add(1, url);
+        String currentDir = this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath();
+
+        if (currentConfigSettings.get("fileOutputPath").trim().isEmpty()) {
+            encryptFile = new File(currentDir + "/" + filename + ".cryptoGX");
+            while (encryptFile.isFile()) {
+                encryptFile = new File(encryptFile.getAbsolutePath() + ".cryptoGX");
+            }
+            if (url.endsWith(".cryptoGX") && filename.endsWith(".cryptoGX")) {
+                decryptFile = new File(currentDir + "/" + filename.substring(0, filename.length() - 9));
+            } else {
+                decryptFile = new File(currentDir + "/" + filename);
+            }
+        } else {
+            encryptFile = new File(currentConfigSettings.get("fileOutputPath") + "/" + filename + ".cryptoGX");
+            while (encryptFile.isFile()) {
+                encryptFile = new File(encryptFile.getAbsolutePath() + ".cryptoGX");
+            }
+            if (url.endsWith(".cryptoGX") && filename.endsWith(".cryptoGX")) {
+                decryptFile = new File(currentConfigSettings.get("fileOutputPath") + "/" + filename.substring(0, filename.length() - 9));
+            } else {
+                decryptFile = new File(currentConfigSettings.get("fileOutputPath") + "/" + filename);
+            }
+        }
+        while (decryptFile.isFile()) {
+            decryptFile = new File(decryptFile.getAbsolutePath() + ".cryptoGX");
+        }
+        inputOutputFiles.add(0, encryptFile);
+        inputOutputFiles.add(1, decryptFile);
+
+        fileEnDecryptInputFiles.getChildren().add(newLabel);
+        enDecryptInputOutputInternetFiles.put(newLabel, fileSpecs);
+        enDecryptInputOutputFiles.put(newLabel, inputOutputFiles);
+    }
+
+    /**
+     * <p>Adds an clipboard image for en- / decryption.
+     * This can be a normal image and an image stream</p>
+     *
+     * @param image that should be added
+     * @throws URISyntaxException
+     */
+    private void fileEnDecryptAddClipboardImage(BufferedImage image) throws URISyntaxException {
+        String filename = "clipboardImage" + System.nanoTime() + ".png";
+        for (Label l: enDecryptInputOutputClipboardImages.keySet()) {
+            if (l.getText().equals(filename)) {
+                return;
+            }
+        }
+        Label newLabel = new Label(filename);
+        newLabel.setOnKeyTyped(this::keyTypedTooltip);
+        newLabel.setOnMouseMoved(this::mouseOverEntryTooltip);
+        newLabel.setOnMouseExited(event -> mouseExitEntryTooltip());
+        newLabel.setOnMouseClicked(event -> {
+            fileEnDecryptSelected(newLabel);
+            fileOutputFilesChangeText(newLabel, null, null);
+            fileEnDecryptLabelEvent = event;
+        });
+        newLabel.setContextMenu(fileEnDecryptInputContextMenu);
+
+        File encryptFile;
+        File decryptFile;
+        String currentDir = this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath();
+        ArrayList<File> inputOutputFiles = new ArrayList<>();
+
+        if (currentConfigSettings.get("fileOutputPath").trim().isEmpty()) {
+            encryptFile = new File(currentDir + "/" + filename + ".cryptoGX");
+            decryptFile = new File(currentDir + "/" + filename);
+        } else {
+            encryptFile = new File(currentConfigSettings.get("fileOutputPath").trim() + "/" + filename + ".cryptoGX");
+            decryptFile = new File(currentConfigSettings.get("fileOutputPath").trim() + "/" + filename);
+        }
+        while (encryptFile.isFile()) {
+            encryptFile = new File(encryptFile.getAbsolutePath() + ".cryptoGX");
+        }
+        while (decryptFile.isFile()) {
+            decryptFile = new File(decryptFile.getAbsolutePath() + ".cryptoGX");
+        }
+        inputOutputFiles.add(0, encryptFile);
+        inputOutputFiles.add(1, decryptFile);
+
+        fileEnDecryptInputFiles.getChildren().add(newLabel);
+        enDecryptInputOutputClipboardImages.put(newLabel, image);
+        enDecryptInputOutputFiles.put(newLabel, inputOutputFiles);
+    }
+
+    /**
+     * <p>Changes the text in the file en- / decryption output file text fields</p>
+     *
+     * @param label
+     * @param encryptOutputFile is the filename of the file it gets encrypted
+     * @param decryptOutputFile is the filename of the file it gets decrypted
+     */
+    private void fileOutputFilesChangeText(Label label, String encryptOutputFile, String decryptOutputFile) {
+        File encryptFile;
+        File decryptFile;
+        ArrayList<File> change = new ArrayList<>();
+        if (encryptOutputFile == null) {
+            encryptFile = enDecryptInputOutputFiles.get(label).get(0);
+        } else {
+            encryptFile = new File(encryptOutputFile);
+        }
+        if (decryptOutputFile == null) {
+            decryptFile = enDecryptInputOutputFiles.get(label).get(1);
+        } else {
+            decryptFile = new File(decryptOutputFile);
+        }
+        change.add(0, encryptFile);
+        change.add(1, decryptFile);
+        if (encryptFile.toString().trim().isEmpty()) {
+            fileEncryptOutputFile.setText("");
+        } else {
+            fileEncryptOutputFile.setText(encryptFile.getAbsolutePath());
+        }
+        if (decryptFile.toString().trim().isEmpty()) {
+            fileDecryptOutputFile.setText("");
+        } else {
+            fileDecryptOutputFile.setText(decryptFile.getAbsolutePath());
+        }
+        enDecryptInputOutputFiles.replace(label, change);
+    }
+
+    /**
+     * <p>Deletes an entry for en- / decryption.
+     * Get called if the user presses 'del' or delete the entry in the en- / decryption box via the right click tooltip</p>
+     *
+     * @see Controller#fileEnDecryptDeleteEntry(Label)
+     */
+    private void fileEnDecryptDeleteEntry() {
+        fileEnDecryptDeleteEntry(choosedLabel);
+    }
+
+    /**
+     * <p>Deletes an entry for en- / decryption.
+     * Get called if the user presses 'del' or delete the entry in the en- / decryption box via the right click tooltip</p>
+     *
+     * @param label that should be deleted
+     */
+    private void fileEnDecryptDeleteEntry(Label label) {
+        enDecryptInputOutputFiles.remove(label);
+        if (fileEnDecryptInputFiles.getChildren().size() - 1 >= 1) {
+            for (int i = 0; i < fileEnDecryptInputFiles.getChildren().size(); i++) {
+                if (fileEnDecryptInputFiles.getChildren().get(i) == label) {
+                    fileEnDecryptInputFiles.getChildren().remove(label);
+                    if (label == choosedLabel) {
+                        try {
+                            choosedLabel = (Label) fileEnDecryptInputFiles.getChildren().get(i - 1);
+                            choosedLabelType = "ENDECRYPT";
+                            fileOutputFilesChangeText(choosedLabel, null, null);
+                            fileEnDecryptSelected(choosedLabel);
+                        } catch (ArrayIndexOutOfBoundsException e) {
+                            e.printStackTrace();
+                            fileOutputFileChangeDest.setDisable(true);
+                            getChoosedLabelOutputFileFolder.setDisable(true);
+                            fileEncryptOutputFile.setEditable(false);
+                            fileDecryptOutputFile.setEditable(false);
+                            fileOutputFilesChangeText(choosedLabel, "", "");
+                            choosedLabel = null;
+                            choosedLabelType = null;
+                        }
+                        break;
+                    }
+                }
+            }
+        } else {
+            fileEnDecryptInputFiles.getChildren().remove(label);
+            fileOutputFileChangeDest.setDisable(true);
+            getChoosedLabelOutputFileFolder.setDisable(true);
+            fileEncryptOutputFile.setEditable(false);
+            fileDecryptOutputFile.setEditable(false);
+            if (label == choosedLabel) {
+                fileOutputFilesChangeText(choosedLabel, "", "");
+                choosedLabel = null;
+                choosedLabelType = null;
+            }
+        }
+    }
+
+    /**
+     * <p>Changes the highlight of the clicked item in the en- / decryption box.
+     * Get called if the user click an non-highlighted item in the en- / decryption box</p>
+     *
+     * @param changeLabel is the label that the user has clicked
+     */
+    private void fileEnDecryptSelected(Label changeLabel) {
+        if (changeLabel != null) {
+            fileDeleteSelected(null);
+            enDecryptInputOutputFiles.keySet().forEach(label -> label.setStyle(null));
+            changeLabel.setStyle("-fx-background-color: lightblue; -fx-border-color: #292929");
+            fileDecryptOutputFile.setEditable(true);
+            fileEncryptOutputFile.setEditable(true);
+            fileOutputFileChangeDest.setDisable(false);
+            getChoosedLabelOutputFileFolder.setDisable(false);
+            choosedLabel = changeLabel;
+            choosedLabelType = "ENDECRYPT";
+        } else {
+            enDecryptInputOutputFiles.keySet().forEach(label -> label.setStyle(null));
+            fileDecryptOutputFile.setEditable(false);
+            fileEncryptOutputFile.setEditable(false);
+            fileOutputFileChangeDest.setDisable(true);
+            getChoosedLabelOutputFileFolder.setDisable(true);
+        }
+    }
+
+    /**
+     * <p>Opens a file chooser GUI where the user can select the files that should be en- / decrypted.
+     * Get called if the 'Choose files...' in the file en- / decrypt section button is pressed</p>
+     */
+    public void fileEnDecryptChoose() {
+        FileChooser fileChooser = new FileChooser();
+        fileChooser.setTitle("Choose files");
+        fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("All files", "*.*"));
+        List<File> files = fileChooser.showOpenMultipleDialog(rootWindow.getScene().getWindow());
+        try {
+            if (files.size() >= 1) {
+                files.forEach(this::fileEnDecryptAddFile);
+            }
+        } catch (NullPointerException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * <p>Get called if user drags a (normal or internet) file over the en- / decrypt file box</p>
+     *
+     * @param event source
+     */
+    public void onFileEnDecryptDragOver(DragEvent event) {
+        Dragboard dragboard = event.getDragboard();
+        if (event.getGestureSource() != fileEnDecryptInputFiles) {
+            if (dragboard.hasFiles()) {
+                if (dragboard.getFiles().size() == 1 && dragboard.getFiles().get(0).isDirectory()) {
+                    return;
+                } else {
+                    event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
+                }
+            } else if (dragboard.hasUrl()) {
+                String url = dragboard.getUrl();
+                String urlFilename = dragboard.getUrl().split("/")[dragboard.getUrl().split("/").length - 1];
+                if (url.startsWith("data:")) {
+                    try {
+                        final int dataStartIndex = url.indexOf(",") + 1;
+                        final String data = url.substring(dataStartIndex);
+                        java.util.Base64.getDecoder().decode(data);
+                        event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                } else if (urlFilename.contains(".") && !Utils.hasAnyCharacter("\\/:*?|<>\"", urlFilename)) {
+                    try {
+                        new URL(url);
+                        event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                        return;
+                    }
+                } else {
+                    event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
+                }
+            }
+        }
+    }
+
+    /**
+     * <p>Get called if the user drops the dragged (normal or internet) file over the en- / decrypt file box</p>
+     *
+     * @param event source
+     * @throws URISyntaxException
+     */
+    public void onFileEnDecryptDragNDrop(DragEvent event) throws URISyntaxException {
+        Dragboard dragboard = event.getDragboard();
+        if (dragboard.hasFiles()) {
+            dragboard.getFiles().forEach(file -> {
+                if (file.isFile()) {
+                    fileEnDecryptAddFile(file);
+                }
+            });
+        } else if (dragboard.hasUrl()) {
+            String url = dragboard.getUrl();
+            String urlFilename = dragboard.getUrl().split("/")[dragboard.getUrl().split("/").length - 1];
+            if (url.startsWith("data:")) {
+                fileEnDecryptAddInternetFile(url, DATAFILEURL);
+            } else if (urlFilename.contains(".") && !Utils.hasAnyCharacter("\\/:*?|<>\"", urlFilename)) {
+                fileEnDecryptAddInternetFile(url, FILEFILEURL);
+            } else {
+                fileEnDecryptAddInternetFile(url, NONSPECIFICFILEURL);
+            }
+        }
+    }
+
+    /**
+     * <p>If the user presses Ctrl + V: Adds the last object in clipboard (if file) for en- / decryption.
+     * Get called if the user presses a key while selected file en- / decryption box</p>
+     *
+     * @param event source
+     * @throws URISyntaxException
+     */
+    public void onFileEnDecryptPaste(KeyEvent event) throws URISyntaxException {
+        if (paste.match(event)) {
+            Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
+            Transferable transferable = clipboard.getContents(null);
+            try {
+                if (transferable != null) {
+                    if (transferable.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
+                        Object objectFileList = transferable.getTransferData(DataFlavor.javaFileListFlavor);
+                        List files = (List) objectFileList;
+                        files.forEach(o -> fileEnDecryptAddFile((File) o));
+                    } else if (transferable.isDataFlavorSupported(DataFlavor.imageFlavor)) {
+                        Object objectImage = transferable.getTransferData(DataFlavor.imageFlavor);
+                        fileEnDecryptAddClipboardImage((BufferedImage) objectImage);
+                    }
+                }
+            } catch (UnsupportedFlavorException | IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * <p>Encrypt all files given files.
+     * Get called if file 'Encrypt' button is pressed</p>
+     */
+    public void fileEncryptButton() {
+        final byte[] salt;
+        if (!fileEnDecryptSaltEntry.getText().isEmpty()) {
+            salt = fileEnDecryptSaltEntry.getText().getBytes(StandardCharsets.UTF_8);
+        } else {
+            salt = new byte[16];
+        }
+        if (!enDecryptInputOutputFiles.isEmpty()) {
+            removeFileFromFileBox.setDisable(true);
+            limitNumberOfThreads.setDisable(true);
+            for(Map.Entry<Label, ArrayList<File>> entry: enDecryptInputOutputFiles.entrySet()) {
+                Thread thread = new Thread(() -> {
+                    addFileEnDecryptThread(Thread.currentThread());
+                    if (limitNumberOfThreads.isSelected()) {
+                        while (totalThreads.get() >= Runtime.getRuntime().availableProcessors()) {
+                            try {
+                                Thread.sleep(100);
+                            } catch (InterruptedException e) {
+                                Thread.currentThread().stop();
+                            }
+                        }
+                    }
+                    totalThreads.getAndIncrement();
+                    Label inputFileLabel = entry.getKey();
+                    ArrayList<File> outputFileList = entry.getValue();
+                    EnDecrypt.AES fileEncrypt = new EnDecrypt.AES(fileEnDecryptKeyEntry.getText(), salt);
+                    if (enDecryptInputOutputInternetFiles.containsKey(inputFileLabel)) {
+                        ArrayList<Object> fileSpecs = enDecryptInputOutputInternetFiles.get(inputFileLabel);
+                        int urlType = (int) fileSpecs.get(0);
+                        String url = (String) fileSpecs.get(1);
+                        try {
+                            if (urlType == FILEFILEURL) {
+                                URLConnection openURL = new URL(url).openConnection();
+                                openURL.addRequestProperty("User-Agent", "Mozilla/5.0");
+                                fileEncrypt.encryptFileLineByLine(openURL.getInputStream(), new FileOutputStream((File) fileSpecs.get(2)));
+                            } else if (urlType == DATAFILEURL) {
+                                final int dataStartIndex = url.indexOf(",") + 1;
+                                final String data = url.substring(dataStartIndex);
+                                byte[] decoded = java.util.Base64.getDecoder().decode(data);
+                                fileEncrypt.encryptFileAllInOne(decoded, new FileOutputStream((File) fileSpecs.get(2)));
+                            } else if (urlType == NONSPECIFICFILEURL) {
+                                URLConnection openURL = new URL(url).openConnection();
+                                openURL.addRequestProperty("User-Agent", "Mozilla/5.0");
+                                fileEncrypt.encryptFileLineByLine(openURL.getInputStream(), new FileOutputStream((File) fileSpecs.get(2)));
+                            }
+                        } catch (FileNotFoundException | InvalidKeySpecException | NoSuchAlgorithmException | MalformedURLException | InvalidKeyException | InvalidAlgorithmParameterException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException e) {
+                            e.printStackTrace();
+                        } catch (IOException e) {
+                            e.printStackTrace();
+                            Platform.runLater(() -> errorAlert("IO Exception occurred", e.getMessage()));
+                        }
+                    } else if (enDecryptInputOutputClipboardImages.containsKey(inputFileLabel)) {
+                        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+                        BufferedImage bufferedImage = enDecryptInputOutputClipboardImages.get(inputFileLabel);
+                        try {
+                            ImageIO.write(bufferedImage, "png", byteArrayOutputStream);
+                            fileEncrypt.encryptFileAllInOne(byteArrayOutputStream.toByteArray(), new FileOutputStream(outputFileList.get(0).getAbsoluteFile()));
+                        } catch (IOException e) {
+                            e.printStackTrace();
+                            Platform.runLater(() -> errorAlert("IO Exception occurred", e.getMessage()));
+                        } catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException | BadPaddingException | InvalidKeySpecException | IllegalBlockSizeException e) {
+                            e.printStackTrace();
+                        }
+                    } else {
+                        try {
+                            fileEncrypt.encryptFileLineByLine(inputFileLabel.getText(), outputFileList.get(0).getAbsolutePath());
+                        } catch (NoSuchPaddingException | InvalidAlgorithmParameterException | NoSuchAlgorithmException | InvalidKeyException | InvalidKeySpecException e) {
+                            e.printStackTrace();
+                        } catch (IOException e) {
+                            e.printStackTrace();
+                            Platform.runLater(() -> errorAlert("IO Exception occurred", e.getMessage()));
+                        }
+                    }
+                    if (removeFileFromFileBox.isSelected()) {
+                        Platform.runLater(() -> fileEnDecryptDeleteEntry(entry.getKey()));
+                    }
+                    if ((getFileEnDecryptThreadsSize() - 1) <= 0) {
+                        fileEnDecryptLoading = false;
+                        Platform.runLater(() -> {
+                            fileEnDecryptLoadingImage.setImage(null);
+                            removeFileFromFileBox.setDisable(false);
+                            limitNumberOfThreads.setDisable(false);
+                        });
+                    }
+                    removeFileEnDecryptThread(Thread.currentThread());
+                    totalThreads.getAndDecrement();
+                });
+                thread.setDaemon(false);
+                thread.start();
+                if (!fileEnDecryptLoading) {
+                    fileEnDecryptLoadingImage.setImage(loadingImage);
+                }
+                fileEnDecryptLoading = true;
+            }
+        }
+    }
+
+    /**
+     * <p>Decrypt all files given files.
+     * Get called if file 'Decrypt' button is pressed</p>
+     */
+    public void fileDecryptButton() {
+        final byte[] salt;
+        if (!fileEnDecryptSaltEntry.getText().isEmpty()) {
+            salt = fileEnDecryptSaltEntry.getText().getBytes(StandardCharsets.UTF_8);
+        } else {
+            salt = new byte[16];
+        }
+        if (!enDecryptInputOutputFiles.isEmpty()) {
+            removeFileFromFileBox.setDisable(true);
+            limitNumberOfThreads.setDisable(true);
+            for(Map.Entry<Label, ArrayList<File>> entry: enDecryptInputOutputFiles.entrySet()) {
+                Thread thread = new Thread(() -> {
+                    addFileEnDecryptThread(Thread.currentThread());
+                    if (limitNumberOfThreads.isSelected()) {
+                        while (totalThreads.get() >= Runtime.getRuntime().availableProcessors()) {
+                            try {
+                                Thread.sleep(100);
+                            } catch (InterruptedException e) {
+                                Thread.currentThread().stop();
+                            }
+                        }
+                    }
+                    totalThreads.getAndIncrement();
+                    Label inputFileLabel = entry.getKey();
+                    ArrayList<File> outputFileList = entry.getValue();
+                    EnDecrypt.AES fileDecrypt = new EnDecrypt.AES(fileEnDecryptKeyEntry.getText(), salt);
+                    if (enDecryptInputOutputInternetFiles.containsKey(entry.getKey())) {
+                        ArrayList<Object> imageSpecs = enDecryptInputOutputInternetFiles.get(entry.getKey());
+                        int urlType = (int) imageSpecs.get(0);
+                        String url = (String) imageSpecs.get(1);
+                        try {
+                            if (urlType == FILEFILEURL) {
+                                URLConnection openURL = new URL(url).openConnection();
+                                openURL.addRequestProperty("User-Agent", "Mozilla/5.0");
+                                fileDecrypt.decryptFileLineByLine(openURL.getInputStream(), new FileOutputStream((File) imageSpecs.get(2)));
+                            } else if (urlType == DATAFILEURL) {
+                                final int dataStartIndex = url.indexOf(",") + 1;
+                                final String data = url.substring(dataStartIndex);
+                                byte[] decoded = java.util.Base64.getDecoder().decode(data);
+                                fileDecrypt.decryptFileAllInOne(decoded, new FileOutputStream((File) imageSpecs.get(2)));
+                            } else if (urlType == NONSPECIFICFILEURL) {
+                                URLConnection openURL = new URL(url).openConnection();
+                                openURL.addRequestProperty("User-Agent", "Mozilla/5.0");
+                                fileDecrypt.decryptFileLineByLine(openURL.getInputStream(), new FileOutputStream((File) imageSpecs.get(2)));
+                            }
+                        } catch (FileNotFoundException | InvalidKeySpecException | NoSuchAlgorithmException | MalformedURLException | InvalidKeyException | InvalidAlgorithmParameterException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException e) {
+                            e.printStackTrace();
+                        } catch (IOException e) {
+                            e.printStackTrace();
+                            Platform.runLater(() -> errorAlert("IO Exception occurred", e.getMessage()));
+                        }
+                    } else if (enDecryptInputOutputClipboardImages.containsKey(inputFileLabel)) {
+                        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+                        BufferedImage bufferedImage = enDecryptInputOutputClipboardImages.get(inputFileLabel);
+                        try {
+                            ImageIO.write(bufferedImage, "png", byteArrayOutputStream);
+                            fileDecrypt.decryptFileAllInOne(byteArrayOutputStream.toByteArray(), new FileOutputStream(outputFileList.get(1).getAbsolutePath()));
+                        } catch (IOException e) {
+                            e.printStackTrace();
+                            Platform.runLater(() -> errorAlert("IO Exception occurred", e.getMessage()));
+                        } catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException | BadPaddingException | InvalidKeySpecException | IllegalBlockSizeException e) {
+                            e.printStackTrace();
+                        }
+                    } else {
+                        try {
+                            fileDecrypt.decryptFileLineByLine(inputFileLabel.getText(), outputFileList.get(1).getAbsolutePath());
+                        } catch (NoSuchPaddingException | InvalidKeySpecException | InvalidKeyException | NoSuchAlgorithmException | InvalidAlgorithmParameterException e) {
+                            e.printStackTrace();
+                        } catch (IOException e) {
+                            e.printStackTrace();
+                            Platform.runLater(() -> errorAlert("IO Exception occurred", e.getMessage()));
+                        } catch (IllegalArgumentException e) {
+                            e.printStackTrace();
+                            Platform.runLater(() -> errorAlert("Wrong text for encryption is given", e.getMessage()));
+                        }
+                    }
+                    if (removeFileFromFileBox.isSelected()) {
+                        Platform.runLater(() -> fileEnDecryptDeleteEntry(entry.getKey()));
+                    }
+                    if ((getFileEnDecryptThreadsSize() - 1) <= 0) {
+                        fileEnDecryptLoading = false;
+                        Platform.runLater(() -> {
+                            fileEnDecryptLoadingImage.setImage(null);
+                            removeFileFromFileBox.setDisable(false);
+                            limitNumberOfThreads.setDisable(false);
+                        });
+                    }
+                    removeFileEnDecryptThread(Thread.currentThread());
+                    totalThreads.getAndDecrement();
+                });
+                thread.setDaemon(false);
+                thread.start();
+                if (!fileEnDecryptLoading) {
+                    fileEnDecryptLoadingImage.setImage(loadingImage);
+                }
+                fileEnDecryptLoading = true;
+            }
+        }
+    }
+
+    /**
+     * <p>Cancels the file en- / decryption.
+     * Get called if the file en- / decrypt 'Cancel' button is pressed</p>
+     */
+    public void fileEnDecryptCancelButton() {
+        for (Iterator<Thread> iterator = getFileEnDecryptThreads().iterator(); iterator.hasNext();) {
+            Thread thread = iterator.next();
+            while (thread.isAlive() && !thread.isInterrupted()) {
+                thread.stop();
+                thread.interrupt();
+            }
+            iterator.remove();
+        }
+        fileEnDecryptLoading = false;
+        fileEnDecryptLoadingImage.setImage(null);
+        removeFileFromFileBox.setDisable(false);
+        limitNumberOfThreads.setDisable(false);
+    }
+
+    //-----fileDelete-----//
+
+    /**
+     * <p>Synchronized method to get the list of threads which delete files</p>
+     *
+     * @return list of threads which delete files
+     */
+    private synchronized List<Thread> getFileDeleteThreads() {
+        return fileDeleteThreads;
+    }
+
+    /**
+     * <p>Synchronized method to get the number of threads which delete files</p>
+     *
+     * @return number of threads which delete files
+     */
+    private synchronized int getFileDeleteThreadsSize() {
+        return fileDeleteThreads.size();
+    }
+
+    /**
+     * <p>Synchronized method to add a thread to the file delete list of current running file delete threads</p>
+     *
+     * @param thread that should be added
+     */
+    private synchronized void addFileDeleteThread(Thread thread) {
+        fileDeleteThreads.add(thread);
+    }
+
+    /**
+     * <p>Synchronized method to remove a thread from the file delete list of current file delete threads</p>
+     *
+     * @param thread that should be removed
+     */
+    private synchronized void removeFileDeleteThread(Thread thread) {
+        fileDeleteThreads.remove(thread);
+    }
+
+    /**
+     * <p>Adds a file that should be deleted</p>
+     *
+     * @param file that should be added
+     */
+    private void fileDeleteAddFile(File file) {
+        for (File f: deleteInputFiles.values()) {
+            if (f.getAbsolutePath().equals(file.getAbsolutePath())) {
+                return;
+            }
+        }
+        Label newLabel = new Label(file.getAbsolutePath());
+        newLabel.setOnKeyTyped(this::keyTypedTooltip);
+        newLabel.setOnMouseMoved(this::mouseOverEntryTooltip);
+        newLabel.setOnMouseExited(event -> mouseExitEntryTooltip());
+        newLabel.setOnMouseClicked(event -> {
+            fileDeleteSelected(newLabel);
+            if (event.getButton() == MouseButton.SECONDARY) {
+                fileDeleteInputContextMenu.show(newLabel, event.getScreenX(), event.getScreenY());
+            }
+        });
+        fileDeleteInputFiles.getChildren().add(newLabel);
+        deleteInputFiles.put(newLabel, file.getAbsoluteFile());
+    }
+
+    /**
+     * <p>Changes the highlight of the clicked item in the file delete box.
+     * Get called if the user click an non-highlighted item in the file delete box</p>
+     *
+     * @param changeLabel is the label that the user has clicked
+     */
+    private void fileDeleteSelected(Label changeLabel) {
+        if (changeLabel != null) {
+            fileEnDecryptSelected(null);
+            deleteInputFiles.keySet().forEach(label -> label.setStyle(null));
+            changeLabel.setStyle("-fx-background-color: lightblue; -fx-border-color: #292929");
+            choosedLabel = changeLabel;
+            choosedLabelType = "DELETE";
+        } else {
+            deleteInputFiles.keySet().forEach(label -> label.setStyle(null));
+        }
+    }
+
+    /**
+     * <p>Deletes an entry for file delete.
+     * Get called if the user presses 'del' or delete the entry in the file delete box via the right click tooltip</p>
+     *
+     * @see Controller#fileEnDecryptDeleteEntry(Label)
+     */
+    private void fileDeleteDeleteEntry() {
+        fileEnDecryptDeleteEntry(choosedLabel);
+    }
+
+    /**
+     * <p>Deletes an entry for file delete.
+     * Get called if the user presses 'del' or delete the entry in the file delete box via the right click tooltip</p>
+     *
+     * @param label that should be deleted
+     */
+    private void fileDeleteDeleteEntry(Label label) {
+        deleteInputFiles.remove(choosedLabel);
+        if (fileDeleteInputFiles.getChildren().size() - 1 >= 1) {
+            for (int i=0; i<fileDeleteInputFiles.getChildren().size(); i++) {
+                if (fileDeleteInputFiles.getChildren().get(i) == choosedLabel) {
+                    fileDeleteInputFiles.getChildren().remove(choosedLabel);
+                    if (label == choosedLabel) {
+                        try {
+                            choosedLabel = (Label) fileDeleteInputFiles.getChildren().get(i - 1);
+                            choosedLabelType = "DELETE";
+                            fileDeleteSelected(choosedLabel);
+                        } catch (ArrayIndexOutOfBoundsException e) {
+                            choosedLabel = null;
+                            choosedLabelType = "DELETE";
+                        }
+                        break;
+                    }
+                }
+            }
+        } else {
+            fileDeleteInputFiles.getChildren().remove(choosedLabel);
+            choosedLabel = null;
+            choosedLabelType = "DELETE";
+        }
+    }
+
+    /**
+     * <p>Opens a file chooser GUI where the user can select the files that should be en- / decrypted.
+     * Get called if the 'Choose files...' in the delete section button is pressed</p>
+     */
+    public void fileDeleteChoose() {
+        FileChooser fileChooser = new FileChooser();
+        fileChooser.setTitle("Choose files");
+        fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("All Files", "*.*"));
+        List<File> files = fileChooser.showOpenMultipleDialog(rootWindow.getScene().getWindow());
+        try {
+            if (files.size() >= 1) {
+                files.forEach(file -> fileDeleteAddFile(file));
+            }
+        } catch (NullPointerException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * <p>Get called if user drags a file over the delete file box</p>
+     *
+     * @param event source
+     */
+    public void onFileDeleteDragOver(DragEvent event) {
+        Dragboard dragboard = event.getDragboard();
+        if (event.getGestureSource() != fileDeleteInputFiles && dragboard.hasFiles()) {
+            if (dragboard.getFiles().size() == 1 && dragboard.getFiles().get(0).isDirectory()) {
+                return;
+            } else {
+                event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
+            }
+        }
+    }
+
+    /**
+     * <p>Get called if the user drops the dragged file over the delete file box</p>
+     *
+     * @param event source
+     */
+    public void onFileDeleteDragNDrop(DragEvent event) {
+        Dragboard dragboard = event.getDragboard();
+        if (dragboard.hasFiles()) {
+            dragboard.getFiles().forEach(file -> {
+                if (file.isFile()) {
+                    fileDeleteAddFile(file);
+                }
+            });
+        }
+    }
+
+    /**
+     * <p>Delete all given files.
+     * Get called if 'Delete' button is pressed</p>
+     */
+    public void fileDelete() {
+        if (!fileDeleteLoading && !deleteInputFiles.isEmpty()) {
+            fileDeleteLoadingImage.setImage(loadingImage);
+        }
+        Iterator<Map.Entry<Label, File>> deleteIterator = deleteInputFiles.entrySet().iterator();
+        while(deleteIterator.hasNext()) {
+            Map.Entry<Label, File> map = deleteIterator.next();
+            Label label = map.getKey();
+            File file = map.getValue();
+            Thread thread = new Thread(() -> {
+                addFileDeleteThread(Thread.currentThread());
+                if (limitNumberOfThreads.isSelected()) {
+                    while (totalThreads.get() >= Runtime.getRuntime().availableProcessors()) {
+                        try {
+                            Thread.sleep(100);
+                        } catch (InterruptedException e) {
+                            Thread.currentThread().stop();
+                        }
+                    }
+                }
+                totalThreads.getAndIncrement();
+                String deleteFile = file.getAbsolutePath();
+                try {
+                    SecureDelete.deleteFileLineByLine(deleteFile, Integer.parseInt(fileDeleteIterationsEntry.getText()));
+                } catch (NoSuchAlgorithmException | IOException e) {
+                    e.printStackTrace();
+                }
+                if ((getFileDeleteThreadsSize() - 1) <= 0) {
+                    fileDeleteLoading = false;
+                    Platform.runLater(() -> fileDeleteLoadingImage.setImage(null));
+                }
+                if (label == choosedLabel) {
+                    choosedLabel = null;
+                    choosedLabelType = null;
+                }
+                Platform.runLater(() -> fileDeleteInputFiles.getChildren().remove(label));
+                removeFileDeleteThread(Thread.currentThread());
+                totalThreads.getAndDecrement();
+            });
+            thread.setDaemon(false);
+            thread.start();
+            fileDeleteLoading = true;
+        }
+    }
+
+    /**
+     * <p>Cancels the file en- / decryption.
+     * Get called if the file delete 'Cancel' button is pressed</p>
+     */
+    public void fileDeleteCancelButton() {
+        for (Iterator<Thread> iterator = getFileDeleteThreads().iterator(); iterator.hasNext();) {
+            Thread thread = iterator.next();
+            while (thread.isAlive() & !thread.isInterrupted()) {
+                thread.stop();
+                thread.interrupt();
+            }
+            iterator.remove();
+        }
+        fileDeleteLoading = false;
+        fileDeleteLoadingImage.setImage(null);
+    }
+
+    /**
+     * Called to initialize a controller after its root element has been
+     * completely processed.
+     *
+     * @param location
+     * The location used to resolve relative paths for the root object, or
+     * <tt>null</tt> if the location is not known.
+     *
+     * @param resources
+     * The resources used to localize the root object, or <tt>null</tt> if
+     * the root object was not localized.
+     */
+    @Override
+    public void initialize(URL location, ResourceBundle resources) {
+
+        //-----general-----//
+
+        currentConfigSettings.put("encryptHash", configDefaultEncryptHash);
+
+        currentConfigSettings.put("textKey", configDefaultTextKey);
+        currentConfigSettings.put("textSalt", configDefaultTextSalt);
+        currentConfigSettings.put("textAlgorithm", configDefaultTextAlgorithm);
+
+        currentConfigSettings.put("fileEnDecryptKey", configDefaultFileEnDecryptKey);
+        currentConfigSettings.put("fileEnDecryptSalt", configDefaultFileEnDecryptSalt);
+        currentConfigSettings.put("fileEnDecryptAlgorithm", configDefaultFileEnDecryptAlgorithm);
+
+        currentConfigSettings.put("fileDeleteIterations", String.valueOf(configDefaultFileDeleteIterations));
+
+        currentConfigSettings.put("fileOutputPath", configDefaultFileOutputPath);
+        currentConfigSettings.put("removeFromFileBox", String.valueOf(configDefaultRemoveFileFromFileBox));
+        currentConfigSettings.put("limitNumberOfThreads", String.valueOf(configDefaultLimitNumberOfThreads));
+
+        textAlgorithms.add("AES");
+        fileEnDecryptAlgorithms.add("AES");
+
+        menubar.setOnMouseDragged(event -> {
+            Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
+            stage.setX(event.getScreenX() + menubarX);
+            stage.setY(event.getScreenY() + menubarY);
+        });
+        menubar.setOnMousePressed(event -> {
+            Scene scene = ((Node) event.getSource()).getScene();
+            menubarX = scene.getX() - event.getSceneX();
+            menubarY = scene.getY() - event.getSceneY();
+        });
+
+        rootWindow.setOnKeyReleased(event -> {
+            if (event.getCode() == KeyCode.DELETE && choosedLabelType != null) {
+                if (choosedLabelType.equals("ENDECRYPT")) {
+                    fileEnDecryptDeleteEntry();
+                } else if (choosedLabelType.equals("DELETE")) {
+                    fileDeleteDeleteEntry();
+                }
+            }
+        });
+
+        getChoosedLabelInputFileFolder.setOnAction(event -> {
+            Desktop desktop = Desktop.getDesktop();
+            String filePath = choosedLabel.getText();
+            try {
+                desktop.open(new File(filePath.substring(0, filePath.lastIndexOf(System.getProperty("file.separator")))));
+            } catch (IOException e) {
+                errorAlert("An unexpected IO Exception occurred", e.getMessage());
+            }
+        });
+
+        getChoosedLabelOutputFileFolder.setOnAction(event -> {
+            Desktop desktop;
+            String filePath;
+            if (enDecryptInputOutputFiles.containsKey(choosedLabel)) {
+                desktop = Desktop.getDesktop();
+                filePath = enDecryptInputOutputFiles.get(choosedLabel).get(0).getAbsolutePath();
+            } else {
+                return;
+            }
+            try {
+                desktop.open(new File(filePath.substring(0, filePath.lastIndexOf(System.getProperty("file.separator")))));
+            } catch (IOException e) {
+                errorAlert("An unexpected IO Exception occurred", e.getMessage());
+            }
+        });
+
+        setDefaultOutputPath.setOnAction(event -> {
+            DirectoryChooser directoryChooser = new DirectoryChooser();
+            File directory = directoryChooser.showDialog(rootWindow.getScene().getWindow());
+            try {
+                currentConfigSettings.replace("fileOutputPath", directory.getAbsolutePath());
+            } catch (NullPointerException e) {
+                e.printStackTrace();
+            }
+        });
+
+        settingsMenu.setOnShowing(event -> {
+            loadSettings.setDisable(!isConfig);
+            exportSettings.setDisable(!isConfig);
+        });
+
+        removeFileFromFileBox.setOnAction(event -> currentConfigSettings.replace("removeFromFileBox", String.valueOf(removeFileFromFileBox.isSelected())));
+        limitNumberOfThreads.setOnAction(event -> currentConfigSettings.replace("limitNumberOfThreads", String.valueOf(limitNumberOfThreads.isSelected())));
+        saveSettings.setOnAction(event -> {
+            try {
+                addSettingGUI(rootWindow.getScene().getWindow(), currentConfigSettings);
+                if (config.isFile()) {
+                    isConfig = true;
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        });
+        loadSettings.setOnAction(event -> {
+            try {
+                currentConfigSettings = (HashMap<String, String>) loadSettingsGUI(rootWindow.getScene().getWindow()).values().toArray()[0];
+                System.out.println(currentConfigSettings);
+                textKeyEntry.setText(currentConfigSettings.get("textKey"));
+                textSaltEntry.setText(currentConfigSettings.get("textSalt"));
+                textAlgorithmBox.setValue(currentConfigSettings.get("textAlgorithm"));
+
+                fileEnDecryptKeyEntry.setText(currentConfigSettings.get("fileEnDecryptKey"));
+                fileEnDecryptSaltEntry.setText(currentConfigSettings.get("fileEnDecryptSalt"));
+                fileEnDecryptAlgorithmBox.setValue(currentConfigSettings.get("fileEnDecryptAlgorithm"));
+
+                fileDeleteIterationsEntry.setText(currentConfigSettings.get("fileDeleteIterations"));
+
+                removeFileFromFileBox.setSelected(Boolean.parseBoolean(currentConfigSettings.get("removeFromFileBox")));
+                limitNumberOfThreads.setSelected(Boolean.parseBoolean(currentConfigSettings.get("limitNumberOfThreads")));
+            } catch (IOException e) {
+                e.printStackTrace();
+            } catch (ArrayIndexOutOfBoundsException ex) {
+                try {
+                    SecureDelete.deleteFileLineByLine(config, 5);
+                    isConfig = false;
+                } catch (NoSuchAlgorithmException | IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        });
+        exportSettings.setOnAction(event -> {
+            try {
+                exportSettingsGUI(rootWindow.getScene().getWindow());
+            } catch (IOException e) {
+                e.printStackTrace();
+                errorAlert("IO Exception occurred", e.getMessage());
+            }
+        });
+        importSettings.setOnAction(event -> {
+            FileChooser fileChooser = new FileChooser();
+            fileChooser.setTitle("Import settings");
+            fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("Config files", "*.config*", "*.xml"), new FileChooser.ExtensionFilter("All files", "*.*"));
+            File file = fileChooser.showOpenDialog(rootWindow.getScene().getWindow());
+            if (file != null) {
+                if (isConfig) {
+                    readUserSettings(file).forEach((Config::addSetting));
+                } else {
+                    writeConfig(readUserSettings(file));
+                    isConfig = true;
+                }
+            }
+        });
+
+        //-----text------//
+
+        textAlgorithmBox.setItems(FXCollections.observableArrayList(textAlgorithms));
+        textAlgorithmBox.setValue(textAlgorithms.get(0));
+
+        //-----fileEnDecrypt-----//
+
+        fileEnDecryptAlgorithmBox.setItems(FXCollections.observableArrayList(fileEnDecryptAlgorithms));
+        fileEnDecryptAlgorithmBox.setValue(fileEnDecryptAlgorithms.get(0));
+
+        MenuItem enDecryptRemove = new MenuItem();
+        enDecryptRemove.setText("Remove");
+        enDecryptRemove.setOnAction(removeEvent -> fileEnDecryptDeleteEntry());
+        MenuItem enDecryptChangeDest = new MenuItem();
+        enDecryptChangeDest.setText("Change output file");
+        enDecryptChangeDest.setOnAction(outputFileChangeEvent -> {
+            FileChooser fileDestChooser = new FileChooser();
+            fileDestChooser.setTitle("Choose or create new file");
+            fileDestChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("All files", "*.*"));
+            File file = fileDestChooser.showSaveDialog(rootWindow.getScene().getWindow());
+            if (file != null) {
+                for (Map.Entry<Label, ArrayList<File>> entry : enDecryptInputOutputFiles.entrySet()) {
+                    if (entry.getKey().getText().equals(choosedLabel.getText())) {
+                        ArrayList<File> changedFile = new ArrayList<>();
+                        changedFile.add(0, file);
+                        changedFile.add(1, file);
+                        enDecryptInputOutputFiles.replace(entry.getKey(), entry.getValue(), changedFile);
+                        fileOutputFilesChangeText((Label) fileEnDecryptLabelEvent.getSource(), file.getAbsolutePath(), file.getAbsolutePath());
+                        break;
+                    }
+                }
+            }
+        });
+        fileEnDecryptInputContextMenu.getItems().addAll(enDecryptRemove, enDecryptChangeDest);
+
+        ContextMenu fileEnDecryptInputFilesMenu = new ContextMenu();
+        MenuItem enDecryptPaste = new MenuItem();
+        enDecryptPaste.setText("Paste");
+        enDecryptPaste.setOnAction(pasteEvent -> {
+            Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
+            Transferable transferable = clipboard.getContents(null);
+            try {
+                if (transferable != null) {
+                    if (transferable.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
+                        Object objectFileList = transferable.getTransferData(DataFlavor.javaFileListFlavor);
+                        List files = (List) objectFileList;
+                        files.forEach(o -> fileEnDecryptAddFile((File) o));
+                    } else if (transferable.isDataFlavorSupported(DataFlavor.imageFlavor)) {
+                        Object objectImage = transferable.getTransferData(DataFlavor.imageFlavor);
+                        fileEnDecryptAddClipboardImage((BufferedImage) objectImage);
+                    }
+                }
+            } catch (UnsupportedFlavorException | IOException | URISyntaxException e) {
+                e.printStackTrace();
+            }
+        });
+        fileEnDecryptInputFilesMenu.getItems().add(enDecryptPaste);
+
+        fileEnDecryptInputFiles.setOnContextMenuRequested(event -> {
+            if (!fileEnDecryptInputContextMenu.isShowing()) {
+                fileEnDecryptInputFilesMenu.show(((VBox) event.getSource()).getParent().getScene().getWindow(), event.getScreenX(), event.getScreenY());
+            }
+        });
+
+        fileOutputFileChangeDest.setOnAction(event -> {
+            FileChooser fileDestChooser = new FileChooser();
+            fileDestChooser.setTitle("Choose or create new file");
+            fileDestChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("All files", "*.*"));
+            File file = fileDestChooser.showSaveDialog(rootWindow.getScene().getWindow());
+            if (file != null) {
+                for (Map.Entry<Label, ArrayList<File>> entry : enDecryptInputOutputFiles.entrySet()) {
+                    if (entry.getKey().getText().equals(choosedLabel.getText())) {
+                        ArrayList<File> changedFile = new ArrayList<>();
+                        changedFile.add(0, file);
+                        changedFile.add(1, file);
+                        enDecryptInputOutputFiles.replace(entry.getKey(), entry.getValue(), changedFile);
+                        fileOutputFilesChangeText((Label) fileEnDecryptLabelEvent.getSource(), file.getAbsolutePath(), file.getAbsolutePath());
+                        break;
+                    }
+                }
+            }
+        });
+
+        fileOutputFileChangeDest.setDisable(true);
+        getChoosedLabelOutputFileFolder.setDisable(true);
+
+        fileEncryptOutputFile.textProperty().addListener((observable, oldValue, newValue) -> {
+            fileOutputFilesChangeText(choosedLabel, newValue, fileDecryptOutputFile.getText());
+        });
+        fileDecryptOutputFile.textProperty().addListener((observable, oldValue, newValue) -> {
+            fileOutputFilesChangeText(choosedLabel, fileEncryptOutputFile.getText(), newValue);
+        });
+
+        //-----fileDelete-----//
+
+        MenuItem deleteRemove = new MenuItem();
+        deleteRemove.setText("Remove");
+        deleteRemove.setOnAction(removeEvent -> fileDeleteDeleteEntry());
+        fileDeleteInputContextMenu.getItems().addAll(deleteRemove);
+
+        ContextMenu fileDeleteInputFilesMenu = new ContextMenu();
+        MenuItem deletePaste = new MenuItem();
+        deletePaste.setText("Paste");
+        deletePaste.setOnAction(pasteEvent -> {
+            Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
+            Transferable transferable = clipboard.getContents(null);
+            try {
+                if (transferable != null && transferable.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
+                    Object objectFileList = transferable.getTransferData(DataFlavor.javaFileListFlavor);
+                    List files = (List) objectFileList;
+                    files.forEach(o -> fileDeleteAddFile((File) o));
+                }
+            } catch (UnsupportedFlavorException | IOException e) {
+                e.printStackTrace();
+            }
+        });
+        fileDeleteInputFilesMenu.getItems().add(deletePaste);
+
+        fileDeleteInputFiles.setOnContextMenuRequested(event -> {
+            if (!fileDeleteInputContextMenu.isShowing()) {
+                fileDeleteInputFilesMenu.show(((VBox) event.getSource()).getParent().getScene().getWindow(), event.getScreenX(), event.getScreenY());
+            }
+        });
+
+        fileDeleteIterationsEntry.textProperty().addListener((observable, oldValue, newValue) -> {
+            if (!newValue.matches("[0-9]*")) {
+                fileDeleteIterationsEntry.setText(oldValue);
+            }
+        });
+
+        Thread t = new Thread(() -> {
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+            if (isConfig) {
+                    Platform.runLater(() -> {
+                        try {
+                            currentConfigSettings = (HashMap<String, String>) loadSettingsGUI(rootWindow.getScene().getWindow()).values().toArray()[0];
+                            System.out.println(currentConfigSettings);
+                            textKeyEntry.setText(currentConfigSettings.get("textKey"));
+                            textSaltEntry.setText(currentConfigSettings.get("textSalt"));
+                            textAlgorithmBox.setValue(currentConfigSettings.get("textAlgorithm"));
+
+                            fileEnDecryptKeyEntry.setText(currentConfigSettings.get("fileEnDecryptKey"));
+                            fileEnDecryptSaltEntry.setText(currentConfigSettings.get("fileEnDecryptSalt"));
+                            fileEnDecryptAlgorithmBox.setValue(currentConfigSettings.get("fileEnDecryptAlgorithm"));
+
+                            fileDeleteIterationsEntry.setText(currentConfigSettings.get("fileDeleteIterations"));
+
+                            removeFileFromFileBox.setSelected(Boolean.parseBoolean(currentConfigSettings.get("removeFromFileBox")));
+                            limitNumberOfThreads.setSelected(Boolean.parseBoolean(currentConfigSettings.get("limitNumberOfThreads")));
+                        } catch (IOException e) {
+                            e.printStackTrace();
+                        } catch (ArrayIndexOutOfBoundsException ex) {
+                            try {
+                                SecureDelete.deleteFileLineByLine(config, 5);
+                                isConfig = false;
+                            } catch (NoSuchAlgorithmException | IOException e) {
+                                e.printStackTrace();
+                            }
+                        }
+                    });
+            }
+        });
+        t.start();
+    }
+}
diff --git a/src/org/blueshard/cryptogx/EnDecrypt.java b/src/org/blueshard/cryptogx/EnDecrypt.java
new file mode 100644
index 0000000..2a49c3b
--- /dev/null
+++ b/src/org/blueshard/cryptogx/EnDecrypt.java
@@ -0,0 +1,531 @@
+package org.blueshard.cryptogx;
+
+import javax.crypto.*;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.security.*;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+import java.util.Arrays;
+import java.util.Base64;
+
+public class EnDecrypt {
+
+    public static class AES extends Thread {
+
+        private int iterations = 1000;
+        private int keyLength = 256;
+
+        private final String key;
+        private final byte[] salt;
+
+        public AES(String key, byte[] salt) {
+            this.key = key;
+            this.salt = salt;
+        }
+
+        public AES(String key, byte[] salt, int iterations) {
+            this.key = key;
+            this.salt = salt;
+            this.iterations = iterations;
+        }
+
+        public AES(String key, byte[] salt, int iterations, int keyLength) {
+            this.key = key;
+            this.salt = salt;
+            this.iterations = iterations;
+            this.keyLength = keyLength;
+        }
+
+        /**
+         * <p>Creates a secret key from given (plain text) key and salt</p>
+         *
+         * @param key from which a secret key should be created
+         * @param salt from which a secret key should be created
+         * @return the secret key
+         * @throws NoSuchAlgorithmException
+         * @throws InvalidKeySpecException
+         */
+        public byte[] createSecretKey(String key, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException {
+            KeySpec keySpec = new PBEKeySpec(key.toCharArray(), salt, this.iterations, keyLength);
+            SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");
+
+            return factory.generateSecret(keySpec).getEncoded();
+        }
+
+        /**
+         * <p>Writes {@param inputStream} to {@param outputStream}</p>
+         *
+         * @param inputStream from which is written
+         * @param outputStream to which is written
+         * @param buffer
+         * @throws IOException
+         */
+        public static void writeLineByLine(InputStream inputStream, OutputStream outputStream, byte[] buffer) throws IOException {
+            int numOfBytesRead;
+            while ((numOfBytesRead = inputStream.read(buffer)) != -1) {
+                outputStream.write(buffer, 0, numOfBytesRead);
+            }
+            outputStream.close();
+            inputStream.close();
+        }
+
+        /**
+         * <p>Encrypts a file randomly line by line</p>
+         *
+         * @see EnDecrypt.AES#encryptRandomLineByLine(InputStream, OutputStream, byte[])
+         */
+        public static void encryptFileRandomLineByLine(File inputFile, File outputFile, byte[] buffer) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, InvalidAlgorithmParameterException {
+            encryptRandomLineByLine(new FileInputStream(inputFile), new FileOutputStream(outputFile), buffer);
+        }
+
+        /**
+         * <p>Encrypts a {@link InputStream} randomly line by line</p>
+         *
+         * @param inputStream that should be encrypted
+         * @param outputStream to which the encrypted {@param inputStream} should be written to
+         * @param buffer
+         * @throws NoSuchAlgorithmException
+         * @throws NoSuchPaddingException
+         * @throws InvalidKeyException
+         * @throws IOException
+         * @throws InvalidAlgorithmParameterException
+         */
+        public static void encryptRandomLineByLine(InputStream inputStream, OutputStream outputStream, byte[] buffer) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, InvalidAlgorithmParameterException {
+            KeyGenerator randomKey = KeyGenerator.getInstance("AES");
+            Key secretKey = new SecretKeySpec(randomKey.generateKey().getEncoded(), "AES");
+
+            Cipher cipher = Cipher.getInstance("AES");
+            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
+
+            CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher);
+            writeLineByLine(cipherInputStream, outputStream, buffer);
+        }
+
+        /**
+         * <p>En- / decrypts the {@param inputFile}</p>
+         *
+         * @param cipherMode says if the file should be en- or decrypted
+         * @param inputFile that should be en- / decrypted
+         * @param outputFile to which the en- / decrypted {@param inputFile} should be written to
+         * @throws InvalidKeySpecException
+         * @throws NoSuchAlgorithmException
+         * @throws NoSuchPaddingException
+         * @throws InvalidKeyException
+         * @throws IOException
+         * @throws BadPaddingException
+         * @throws IllegalBlockSizeException
+         */
+        public void enDecryptFileAllInOne(int cipherMode, File inputFile, File outputFile) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, BadPaddingException, IllegalBlockSizeException {
+            Key secretKey = new SecretKeySpec(createSecretKey(key, salt), "AES");
+
+            Cipher cipher = Cipher.getInstance("AES");
+            cipher.init(cipherMode, secretKey);
+
+            FileInputStream inputStream = new FileInputStream(inputFile);
+            byte[] inputBytes = new byte[(int) inputFile.length()];
+            inputStream.read(inputBytes);
+
+            byte[] outputBytes = cipher.doFinal(inputBytes);
+
+            FileOutputStream outputStream = new FileOutputStream(outputFile);
+            outputStream.write(outputBytes);
+
+            inputStream.close();
+            outputStream.close();
+        }
+
+        /**
+         * <p>En- / decrypts the {@param inputBytes}</p>
+         *
+         * @param cipherMode says if the file should be en- or decrypted
+         * @param inputBytes that should be en- / decrypted
+         * @param outputStream to which the en- / decrypted {@param inputFile} should be written to
+         * @throws InvalidKeySpecException
+         * @throws NoSuchAlgorithmException
+         * @throws NoSuchPaddingException
+         * @throws InvalidKeyException
+         * @throws IOException
+         * @throws BadPaddingException
+         * @throws IllegalBlockSizeException
+         */
+        public void enDecryptFileAllInOne(int cipherMode, byte[] inputBytes, OutputStream outputStream) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, BadPaddingException, IllegalBlockSizeException {
+            Key secretKey = new SecretKeySpec(createSecretKey(key, salt), "AES");
+
+            Cipher cipher = Cipher.getInstance("AES");
+            cipher.init(cipherMode, secretKey);
+
+            byte[] outputBytes = cipher.doFinal(inputBytes);
+
+            outputStream.write(outputBytes);
+
+            outputStream.close();
+        }
+
+        /**
+         * <p>En- / decrypts the {@param inputFile}</p>
+         *
+         * @param cipherMode says if the file should be en- or decrypted
+         * @param inputFile that should be en- / decrypted
+         * @param outputFile to which the en- / decrypted {@param inputFile} should be written to
+         * @param buffer
+         * @throws InvalidKeySpecException
+         * @throws NoSuchAlgorithmException
+         * @throws NoSuchPaddingException
+         * @throws InvalidKeyException
+         * @throws IOException
+         * @throws InvalidAlgorithmParameterException
+         */
+        public void enDecryptLineByLine(int cipherMode, File inputFile, File outputFile, byte[] buffer) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, InvalidAlgorithmParameterException {
+            Key secretKey = new SecretKeySpec(createSecretKey(key, salt), "AES");
+
+            Cipher cipher = Cipher.getInstance("AES");
+            cipher.init(cipherMode, secretKey);
+
+            FileInputStream fileInputStream = new FileInputStream(inputFile);
+            FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
+
+            if (cipherMode == Cipher.ENCRYPT_MODE) {
+                CipherInputStream cipherInputStream = new CipherInputStream(fileInputStream, cipher);
+                writeLineByLine(cipherInputStream, fileOutputStream, buffer);
+            } else if (cipherMode == Cipher.DECRYPT_MODE) {
+                CipherOutputStream cipherOutputStream = new CipherOutputStream(fileOutputStream, cipher);
+                writeLineByLine(fileInputStream, cipherOutputStream, buffer);
+            }
+        }
+
+        /**
+         * <p>En- / decrypts the {@param inputStream}</p>
+         *
+         * @param cipherMode says if the file should be en- or decrypted
+         * @param inputStream that should be en- / decrypted
+         * @param outputStream to which the en- / decrypted {@param inputFile} should be written to
+         * @param buffer
+         * @throws InvalidKeySpecException
+         * @throws NoSuchAlgorithmException
+         * @throws NoSuchPaddingException
+         * @throws InvalidKeyException
+         * @throws IOException
+         * @throws InvalidAlgorithmParameterException
+         */
+        public void enDecryptLineByLine(int cipherMode, InputStream inputStream, OutputStream outputStream, byte[] buffer) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, InvalidAlgorithmParameterException {
+            Key secretKey = new SecretKeySpec(createSecretKey(key, salt), "AES");
+
+            Cipher cipher = Cipher.getInstance("AES");
+            cipher.init(cipherMode, secretKey);
+
+            if (cipherMode == Cipher.ENCRYPT_MODE) {
+                CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher);
+                writeLineByLine(cipherInputStream, outputStream, buffer);
+            } else if (cipherMode == Cipher.DECRYPT_MODE) {
+                CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream, cipher);
+                writeLineByLine(inputStream, cipherOutputStream, buffer);
+            }
+        }
+
+        /**
+         * <p>Encrypt {@param bytes} randomly</p>
+         *
+         * @see EnDecrypt.AES#encryptRandom(byte[])
+         */
+        public static String encryptRandom(String string) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
+            return encryptRandom(string.getBytes(StandardCharsets.UTF_8));
+        }
+
+        /**
+         * <p>Encrypt {@param bytes} randomly</p>
+         *
+         * @param bytes that should be encrypted
+         * @return the encrypted {@param bytes} as {@link String}
+         * @throws NoSuchPaddingException
+         * @throws NoSuchAlgorithmException
+         * @throws InvalidKeyException
+         * @throws BadPaddingException
+         * @throws IllegalBlockSizeException
+         */
+        public static String encryptRandom(byte[] bytes) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
+            KeyGenerator randomKey = KeyGenerator.getInstance("AES");
+            Key secretKey = new SecretKeySpec(randomKey.generateKey().getEncoded(), "AES");
+
+            Cipher encryptRandomCipher = Cipher.getInstance("AES");
+            encryptRandomCipher.init(Cipher.ENCRYPT_MODE, secretKey);
+            return Base64.getEncoder().encodeToString(encryptRandomCipher.doFinal(bytes));
+        }
+
+        /**
+         * <p>Encrypts a file randomly at once</p>
+         *
+         * @see EnDecrypt.AES#encryptFileRandomAllInOne(File, File)
+         */
+        public static void encryptFileRandomAllInOne(String inputFilename, String outputFilename) throws NoSuchPaddingException, NoSuchAlgorithmException, IOException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException {
+            encryptFileRandomAllInOne(new File(inputFilename), new File(outputFilename));
+        }
+
+        /**
+         * <p>Encrypts a file randomly at once</p>
+         *
+         * @param inputFile that should be encrypted
+         * @param outputFile to which the encrypted file should be written to
+         * @throws NoSuchAlgorithmException
+         * @throws NoSuchPaddingException
+         * @throws InvalidKeyException
+         * @throws IOException
+         * @throws BadPaddingException
+         * @throws IllegalBlockSizeException
+         */
+        public static void encryptFileRandomAllInOne(File inputFile, File outputFile) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, BadPaddingException, IllegalBlockSizeException {
+            KeyGenerator randomKey = KeyGenerator.getInstance("AES");
+            Key secretKey = new SecretKeySpec(randomKey.generateKey().getEncoded(), "AES");
+
+            Cipher cipher = Cipher.getInstance("AES");
+            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
+
+            FileInputStream inputStream = new FileInputStream(inputFile);
+            byte[] inputBytes = new byte[(int) inputFile.length()];
+            inputStream.read(inputBytes);
+
+            byte[] outputBytes = cipher.doFinal(inputBytes);
+
+            FileOutputStream outputStream = new FileOutputStream(outputFile);
+            outputStream.write(outputBytes);
+
+            inputStream.close();
+            outputStream.close();
+        }
+
+        /**
+         * <p>Encrypts {@param inputFilename} randomly line by line and write it to {@param outputFilename}</p>
+         *
+         * @see EnDecrypt.AES#encryptRandomLineByLine(InputStream, OutputStream, byte[])
+         */
+        public static void encryptFileRandomLineByLine(String inputFilename, String outputFilename) throws InvalidKeyException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, NoSuchPaddingException, IOException {
+            encryptRandomLineByLine(new FileInputStream(inputFilename), new FileOutputStream(outputFilename), new byte[64]);
+        }
+
+        /**
+         * <p>Encrypts {@param inputFilename} randomly line by line and write it to {@param outputFilename}</p>
+         *
+         * @see EnDecrypt.AES#encryptRandomLineByLine(InputStream, OutputStream, byte[])
+         */
+        public static void encryptFileRandomLineByLine(String inputFilename, String outputFilename, byte[] buffer) throws InvalidKeyException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, NoSuchPaddingException, IOException {
+            encryptRandomLineByLine(new FileInputStream(inputFilename), new FileOutputStream(outputFilename), buffer);
+        }
+
+        /**
+         * <p>Decrypt encrypted {@param encryptedString}</p>
+         *
+         * @see EnDecrypt.AES#decrypt(byte[])
+         */
+        public String decrypt(String encryptedString) throws BadPaddingException, IllegalBlockSizeException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException {
+            Key secretKey = new SecretKeySpec(createSecretKey(key, salt), "AES");
+
+            Cipher decryptCipher = Cipher.getInstance("AES");
+            decryptCipher.init(Cipher.DECRYPT_MODE, secretKey);
+            return new String(decryptCipher.doFinal(Base64.getDecoder().decode(encryptedString)), StandardCharsets.UTF_8);
+        }
+
+        /**
+         * <p>Decrypt encrypted {@param bytes}</p>
+         *
+         * @param bytes that should be decrypted
+         * @return decrypted bytes
+         * @throws BadPaddingException
+         * @throws IllegalBlockSizeException
+         * @throws NoSuchPaddingException
+         * @throws NoSuchAlgorithmException
+         * @throws InvalidKeySpecException
+         * @throws InvalidKeyException
+         */
+        public byte[] decrypt(byte[] bytes) throws BadPaddingException, IllegalBlockSizeException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException {
+            return decrypt(Arrays.toString(bytes)).getBytes(StandardCharsets.UTF_8);
+        }
+
+        /**
+         * <p>Encrypt {@param bytes}</p>
+         *
+         * @see EnDecrypt.AES#encrypt(byte[])
+         */
+        public String encrypt(String string) throws BadPaddingException, IllegalBlockSizeException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException {
+            return Base64.getEncoder().encodeToString(encrypt(string.getBytes(StandardCharsets.UTF_8)));
+        }
+
+        /**
+         * <p>Encrypt {@param bytes}</p>
+         *
+         * @param bytes that should be encrypted
+         * @return encrypted bytes
+         * @throws BadPaddingException
+         * @throws IllegalBlockSizeException
+         * @throws NoSuchPaddingException
+         * @throws NoSuchAlgorithmException
+         * @throws InvalidKeySpecException
+         * @throws InvalidKeyException
+         */
+        public byte[] encrypt(byte[] bytes) throws BadPaddingException, IllegalBlockSizeException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException {
+            Key secretKey = new SecretKeySpec(createSecretKey(key, salt), "AES");
+
+            Cipher encryptCipher = Cipher.getInstance("AES");
+            encryptCipher.init(Cipher.ENCRYPT_MODE, secretKey);
+            return encryptCipher.doFinal(bytes);
+        }
+
+        /**
+         * <p>Decrypt encrypted {@param inputFilename} to {@param outputFilename} at once</p>
+         *
+         * @param inputFilename that should be decrypted
+         * @param outputFilename to which the decrypted content should be written to
+         * @throws NoSuchPaddingException
+         * @throws NoSuchAlgorithmException
+         * @throws IOException
+         * @throws BadPaddingException
+         * @throws IllegalBlockSizeException
+         * @throws InvalidKeyException
+         * @throws InvalidKeySpecException
+         */
+        public void decryptFileAllInOne(String inputFilename, String outputFilename) throws NoSuchPaddingException, NoSuchAlgorithmException, IOException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, InvalidKeySpecException {
+            enDecryptFileAllInOne(Cipher.DECRYPT_MODE, new File(inputFilename), new File(outputFilename));
+        }
+
+        /**
+         * <p>Decrypt encrypted {@param inputBytes} to {@param outputStream} at once</p>
+         *
+         * @param inputBytes that should be decrypted
+         * @param outputStream to which the decrypted content should be written to
+         * @throws NoSuchPaddingException
+         * @throws NoSuchAlgorithmException
+         * @throws IOException
+         * @throws BadPaddingException
+         * @throws IllegalBlockSizeException
+         * @throws InvalidKeyException
+         * @throws InvalidKeySpecException
+         */
+        public void decryptFileAllInOne(byte[] inputBytes, OutputStream outputStream) throws NoSuchPaddingException, NoSuchAlgorithmException, IOException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, InvalidKeySpecException {
+            enDecryptFileAllInOne(Cipher.DECRYPT_MODE, inputBytes, outputStream);
+        }
+
+        /**
+         * <p>Decrypt encrypted {@param inputFilename} to {@param outputFilename} line by line</p>
+         *
+         * @see EnDecrypt.AES#decryptFileLineByLine(InputStream, OutputStream, byte[])
+         */
+        public void decryptFileLineByLine(String inputFilename, String outputFilename) throws NoSuchPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException, InvalidKeyException, InvalidKeySpecException {
+            enDecryptLineByLine(Cipher.DECRYPT_MODE, new File(inputFilename), new File(outputFilename), new byte[64]);
+        }
+
+        /**
+         * <p>Decrypt encrypted {@param inputStream} to {@param outputStream} line by line</p>
+         *
+         * @see EnDecrypt.AES#decryptFileLineByLine(InputStream, OutputStream, byte[])
+         */
+        public void decryptFileLineByLine(InputStream inputStream, OutputStream outputStream) throws NoSuchPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException, InvalidKeyException, InvalidKeySpecException {
+            enDecryptLineByLine(Cipher.DECRYPT_MODE, inputStream, outputStream, new byte[64]);
+        }
+
+        /**
+         * <p>Decrypt encrypted {@param inputFilename} to {@param outputFilename} line by line</p>
+         *
+         * @see EnDecrypt.AES#decryptFileLineByLine(InputStream, OutputStream, byte[])
+         */
+        public void decryptFileLineByLine(String inputFilename, String outputFilename, byte[] buffer) throws NoSuchPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException, InvalidKeyException, InvalidKeySpecException {
+            enDecryptLineByLine(Cipher.DECRYPT_MODE, new File(inputFilename), new File(outputFilename), buffer);
+        }
+
+        /**
+         * <p>Decrypt encrypted {@param inputStream} to {@param outputStream} line by line</p>
+         *
+         * @param inputStream that should be decrypted
+         * @param outputStream to which the decrypted content should be written to
+         * @param buffer
+         * @throws NoSuchPaddingException
+         * @throws InvalidAlgorithmParameterException
+         * @throws NoSuchAlgorithmException
+         * @throws IOException
+         * @throws InvalidKeyException
+         * @throws InvalidKeySpecException
+         */
+        public void decryptFileLineByLine(InputStream inputStream, OutputStream outputStream, byte[] buffer) throws NoSuchPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException, InvalidKeyException, InvalidKeySpecException {
+            enDecryptLineByLine(Cipher.DECRYPT_MODE, inputStream, outputStream, buffer);
+        }
+
+        /**
+         * <p>DEncrypt {@param inputFilename} to {@param outputFilename} at once</p>
+         *
+         * @param inputFilename that should be encrypt
+         * @param outputFilename to which the encrypted content should be written to
+         * @throws NoSuchPaddingException
+         * @throws NoSuchAlgorithmException
+         * @throws IOException
+         * @throws BadPaddingException
+         * @throws IllegalBlockSizeException
+         * @throws InvalidKeyException
+         * @throws InvalidKeySpecException
+         */
+        public void encryptFileAllInOne(String inputFilename, String outputFilename) throws NoSuchPaddingException, NoSuchAlgorithmException, IOException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, InvalidKeySpecException {
+            enDecryptFileAllInOne(Cipher.ENCRYPT_MODE, new File(inputFilename), new File(outputFilename));
+        }
+
+        /**
+         * <p>Encrypt {@param inputBytes} to {@param outputStream} at once</p>
+         *
+         * @param inputBytes that should be encrypted
+         * @param outputStream to which the encrypted content should be written to
+         * @throws NoSuchPaddingException
+         * @throws NoSuchAlgorithmException
+         * @throws IOException
+         * @throws BadPaddingException
+         * @throws IllegalBlockSizeException
+         * @throws InvalidKeyException
+         * @throws InvalidKeySpecException
+         */
+        public void encryptFileAllInOne(byte[] inputBytes, OutputStream outputStream) throws NoSuchPaddingException, NoSuchAlgorithmException, IOException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, InvalidKeySpecException {
+            enDecryptFileAllInOne(Cipher.ENCRYPT_MODE, inputBytes, outputStream);
+        }
+
+        /**
+         * <p>Encrypt {@param inputFilename} to {@param outputFilename} line by line</p>
+         *
+         * @see EnDecrypt.AES#encryptFileLineByLine(InputStream, OutputStream, byte[])
+         */
+        public void encryptFileLineByLine(String inputFilename, String outputFilename) throws NoSuchPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException, InvalidKeyException, InvalidKeySpecException {
+            enDecryptLineByLine(Cipher.ENCRYPT_MODE, new File(inputFilename), new File(outputFilename), new byte[64]);
+        }
+
+        /**
+         * <p>Encrypt {@param inputStream} to {@param outputStream} line by line</p>
+         *
+         * @see EnDecrypt.AES#encryptFileLineByLine(InputStream, OutputStream, byte[])
+         */
+        public void encryptFileLineByLine(InputStream inputStream, OutputStream outputStream) throws NoSuchPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException, InvalidKeyException, InvalidKeySpecException {
+            enDecryptLineByLine(Cipher.ENCRYPT_MODE, inputStream, outputStream, new byte[64]);
+        }
+
+        /**
+         * <p>Encrypt {@param inputFilename} to {@param outputFilename} line by line</p>
+         *
+         * @see EnDecrypt.AES#encryptFileLineByLine(InputStream, OutputStream, byte[])
+         */
+        public void encryptFileLineByLine(String inputFilename, String outputFilename, byte[] buffer) throws NoSuchPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException, InvalidKeyException, InvalidKeySpecException {
+            enDecryptLineByLine(Cipher.ENCRYPT_MODE, new File(inputFilename), new File(outputFilename), buffer);
+        }
+
+        /**
+         * <p>Encrypt {@param inputStream} to {@param outputStream} line by line</p>
+         *
+         * @param inputStream that should be encrypted
+         * @param outputStream to which the encrypted {@param inputStream} should be written to
+         * @param buffer
+         * @throws NoSuchPaddingException
+         * @throws InvalidAlgorithmParameterException
+         * @throws NoSuchAlgorithmException
+         * @throws IOException
+         * @throws InvalidKeyException
+         * @throws InvalidKeySpecException
+         */
+        public void encryptFileLineByLine(InputStream inputStream, OutputStream outputStream, byte[] buffer) throws NoSuchPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException, InvalidKeyException, InvalidKeySpecException {
+            enDecryptLineByLine(Cipher.ENCRYPT_MODE, inputStream, outputStream, buffer);
+        }
+
+    }
+}
diff --git a/src/org/blueshard/cryptogx/Main.java b/src/org/blueshard/cryptogx/Main.java
new file mode 100644
index 0000000..65a9fe7
--- /dev/null
+++ b/src/org/blueshard/cryptogx/Main.java
@@ -0,0 +1,269 @@
+/**
+ *
+ * @author blueShard
+ * @version 1.11.0
+ */
+
+package org.blueshard.cryptogx;
+
+import javafx.application.Application;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.*;
+import javafx.scene.image.Image;
+import javafx.stage.Screen;
+import javafx.stage.Stage;
+import javafx.stage.StageStyle;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.swing.*;
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicReference;
+
+public class Main extends Application {
+
+    protected static final int NON_PORTABLE = 414729643;
+    protected static final int PORTABLE = 245714766;
+
+    protected static final int TYPE = PORTABLE;
+
+    protected final static String configDefaultName = "";
+    protected final static String configDefaultEncryptHash = "";
+    protected final static String configDefaultTextKey = "";
+    protected final static String configDefaultTextSalt = "";
+    protected final static String configDefaultTextAlgorithm = "AES";
+    protected final static String configDefaultFileEnDecryptKey = "";
+    protected final static String configDefaultFileEnDecryptSalt = "";
+    protected final static String configDefaultFileEnDecryptAlgorithm = "AES";
+    protected final static int configDefaultFileDeleteIterations = 5;
+    protected final static String configDefaultFileOutputPath = "";
+    protected final static boolean configDefaultRemoveFileFromFileBox = false;
+    protected final static boolean configDefaultLimitNumberOfThreads = true;
+
+    protected static ArrayList<String> textAlgorithms = new ArrayList<>();
+    protected static ArrayList<String> fileEnDecryptAlgorithms = new ArrayList<>();
+
+    private static Stage mainStage;
+    private double rootWindowX, rootWindowY;
+    protected static File config;
+    protected static boolean isConfig;
+
+    /**
+     * <p>Start the GUI</p>
+     *
+     * @param primaryStage of the GUI
+     * @throws IOException if issues with loading 'mainGUI.fxml'
+     */
+    @Override
+    public void start(Stage primaryStage) throws IOException {
+        Thread.setDefaultUncaughtExceptionHandler(Main::exceptionAlert);
+
+        mainStage = primaryStage;
+
+        Parent root = FXMLLoader.load(getClass().getResource("resources/mainGUI.fxml"));
+        primaryStage.initStyle(StageStyle.UNDECORATED);
+        primaryStage.setResizable(false);
+        primaryStage.setTitle("cryptoGX");
+        primaryStage.getIcons().add(new Image(getClass().getResource("resources/cryptoGX.png").toExternalForm()));
+        Scene scene = new Scene(root, 900, 470);
+
+        scene.setOnMouseDragged(event -> {
+            primaryStage.setX(event.getScreenX() + rootWindowX);
+            primaryStage.setY(event.getScreenY() + rootWindowY);
+        });
+        scene.setOnMousePressed(event -> {
+            rootWindowX = scene.getX() - event.getSceneX();
+            rootWindowY = scene.getY() - event.getSceneY();
+        });
+
+        primaryStage.setScene(scene);
+        primaryStage.show();
+    }
+
+    /**
+     * <p>Enter method for the application.
+     * Can also be used to en- / decrypt text and files or secure delete files without starting GUI</p>
+     *
+     * @param args from the command line
+     * @return status
+     * @throws BadPaddingException
+     * @throws NoSuchAlgorithmException if wrong algorithm is given (command line)
+     * @throws IllegalBlockSizeException if wrong size for key is given (command line)
+     * @throws NoSuchPaddingException
+     * @throws InvalidKeyException if invalid key is given (command line)
+     * @throws InvalidKeySpecException
+     * @throws IOException if files cannot be en- / decrypted or deleted correctly (command line)
+     * @throws InvalidAlgorithmParameterException if wrong algorithm parameters are given (command line)
+     */
+    public static void main(String[] args) throws BadPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, NoSuchPaddingException, InvalidKeyException, InvalidKeySpecException, IOException, InvalidAlgorithmParameterException {
+        if (Main.TYPE == Main.NON_PORTABLE) {
+            if (System.getProperty("os.name").toLowerCase().startsWith("windows")) {
+                config = new File("C:\\Users\\" + System.getProperty("user.name") + "\\AppData\\Roaming\\cryptoGX\\cryptoGX.config");
+            } else {
+                config = new File("cryptoGX.config");
+            }
+        } else {
+            config = new File("cryptoGX.config");
+        }
+        isConfig = config.isFile();
+        if (args.length == 0) {
+            String version = Runtime.class.getPackage().getImplementationVersion();
+            if (version.startsWith("1.")) {
+                if (Integer.parseInt(version.substring(2, 3)) < 8) {
+                    System.out.println("1");
+                    JOptionPane.showMessageDialog(null, "Please use java 1.8.0_240 to java 10.*", "ERROR", JOptionPane.ERROR_MESSAGE);
+                } else if (Integer.parseInt(version.substring(6, 9)) < 240) {
+                    JOptionPane.showMessageDialog(null, "Please use java 1.8.0_240 to java 10.*", "ERROR", JOptionPane.ERROR_MESSAGE);
+                }
+            } else if (Integer.parseInt(version.substring(0, 2)) > 10) {
+                    JOptionPane.showMessageDialog(null, "Please use java 1.8.0_240 to java 10.*", "ERROR", JOptionPane.ERROR_MESSAGE);
+                } else {
+                    JOptionPane.showMessageDialog(null, "Please use java 1.8.0_240 to java 10.*", "ERROR", JOptionPane.ERROR_MESSAGE);
+                }
+            launch(args);
+        } else {
+            args[0] = args[0].replace("-", "");
+            if (args[0].toLowerCase().equals("help") || args[0].toUpperCase().equals("H")) {
+                System.out.println("Usage AES: \n\n" +
+                        "    Text en- / decryption\n" +
+                        "        encrypt: <cryptoGX jar file> AES <key> <salt> encrypt <string>\n" +
+                        "        decrypt: <cryptoGX jar file> AES <key> <salt> decrypt <encrypted string>\n\n" +
+                        "    File en- / decryption\n" +
+                        "        encrypt: <cryptoGX jar file> AES <key> <salt> encrypt <path of file to encrypt> <encrypted file dest>\n" +
+                        "        decrypt: <cryptoGX jar file> AES <key> <salt> decrypt <encrypted file path> <decrypted file dest>\n\n" +
+                        "File secure delete: <iterations> <path of file to delete>");
+            } else if (args[0].toLowerCase().equals("delete")) {
+                if (args.length > 3) {
+                    System.err.println("To many arguments were given, expected 3");
+                } else if (args.length < 3) {
+                    System.err.println("To few arguments were given, expected 3");
+                }
+                try {
+                    SecureDelete.deleteFileLineByLine(args[2], Integer.parseInt(args[1]));
+                } catch (NumberFormatException e) {
+                    System.err.println(args[1] + " must be a number\n Error: " + e.getMessage());
+                }
+            } else if (args[0].toLowerCase().equals("aes")) {
+                if (args.length < 4) {
+                    System.err.println("To few arguments were given");
+                    System.exit(1);
+                }
+                EnDecrypt.AES aes;
+                if (args[2].isEmpty()) {
+                    aes = new EnDecrypt.AES(args[1], new byte[16]);
+                } else {
+                    aes = new EnDecrypt.AES(args[1], args[2].getBytes(StandardCharsets.UTF_8));
+                }
+                String type = args[3].toLowerCase();
+                if (type.equals("encrypt")) {
+                    System.out.println(aes.encrypt(args[4]));
+                } else if (type.equals("decrypt")) {
+                    System.out.println(aes.decrypt(args[4]));
+                } else if (type.equals("fileencrypt") || type.equals("encryptfile")) {
+                    aes.encryptFileLineByLine(args[4], args[5]);
+                } else if (type.equals("filedecrypt") ||type.equals("decryptfile")) {
+                    aes.decryptFileLineByLine(args[4], args[5]);
+                }
+            }
+        }
+        System.exit(0);
+    }
+
+    /**
+     * <p>"Catch" all uncatched exceptions and opens an alert window</p>
+     *
+     * @param thread which called this method
+     * @param throwable of the thread which called the method
+     */
+    private static void exceptionAlert(Thread thread, Throwable throwable) {
+        throwable.printStackTrace();
+
+        AtomicReference<Double> exceptionAlertX = new AtomicReference<>(Screen.getPrimary().getBounds().getMaxX() / 2);
+        AtomicReference<Double> exceptionAlertY = new AtomicReference<>(Screen.getPrimary().getBounds().getMaxY() / 2);
+
+        Alert enDecryptError = new Alert(Alert.AlertType.ERROR, "Error: " + throwable, ButtonType.OK);
+        enDecryptError.initStyle(StageStyle.UNDECORATED);
+        enDecryptError.setTitle("Error");
+        ((Stage) enDecryptError.getDialogPane().getScene().getWindow()).getIcons().add(new Image(Main.class.getResource("resources/cryptoGX.png").toExternalForm()));
+
+        Scene window = enDecryptError.getDialogPane().getScene();
+
+        window.setOnMouseDragged(dragEvent -> {
+            enDecryptError.setX(dragEvent.getScreenX() + exceptionAlertX.get());
+            enDecryptError.setY(dragEvent.getScreenY() + exceptionAlertY.get());
+        });
+        window.setOnMousePressed(pressEvent -> {
+            exceptionAlertX.set(window.getX() - pressEvent.getSceneX());
+            exceptionAlertY.set(window.getY() - pressEvent.getSceneY());
+        });
+
+        enDecryptError.show();
+    }
+
+    /**
+     * <p>Shows an error alert window</p>
+     *
+     * @param message which will the alert show
+     * @param error which will show after the message
+     */
+    protected static void errorAlert(String message, String error) {
+        AtomicReference<Double> alertX = new AtomicReference<>(Screen.getPrimary().getBounds().getMaxX() / 2);
+        AtomicReference<Double> alertY = new AtomicReference<>(Screen.getPrimary().getBounds().getMaxY() / 2);
+
+        Alert enDecryptError = new Alert(Alert.AlertType.ERROR, message +
+                "\nError: " + error, ButtonType.OK);
+        enDecryptError.initStyle(StageStyle.UNDECORATED);
+        enDecryptError.setTitle("Error");
+        ((Stage) enDecryptError.getDialogPane().getScene().getWindow()).getIcons().add(new Image(Main.class.getResource("resources/cryptoGX.png").toExternalForm()));
+
+        Scene window = enDecryptError.getDialogPane().getScene();
+
+        window.setOnMouseDragged(dragEvent -> {
+            enDecryptError.setX(dragEvent.getScreenX() + alertX.get());
+            enDecryptError.setY(dragEvent.getScreenY() + alertY.get());
+        });
+        window.setOnMousePressed(pressEvent -> {
+            alertX.set(window.getX() - pressEvent.getSceneX());
+            alertY.set(window.getY() - pressEvent.getSceneY());
+        });
+
+        enDecryptError.show();
+    }
+
+    /**
+     * <p>Shows an warning alert window</p>
+     *
+     * @param message that the alert window will show
+     */
+    protected static void warningAlert(String message) {
+        AtomicReference<Double> alertX = new AtomicReference<>(Screen.getPrimary().getBounds().getMaxX() / 2);
+        AtomicReference<Double> alertY = new AtomicReference<>(Screen.getPrimary().getBounds().getMaxY() / 2);
+
+        Alert enDecryptError = new Alert(Alert.AlertType.WARNING, message, ButtonType.OK);
+        enDecryptError.initStyle(StageStyle.UNDECORATED);
+        enDecryptError.setTitle("Error");
+        ((Stage) enDecryptError.getDialogPane().getScene().getWindow()).getIcons().add(new Image(Main.class.getResource("resources/cryptoGX.png").toExternalForm()));
+
+        Scene window = enDecryptError.getDialogPane().getScene();
+
+        window.setOnMouseDragged(dragEvent -> {
+            enDecryptError.setX(dragEvent.getScreenX() + alertX.get());
+            enDecryptError.setY(dragEvent.getScreenY() + alertY.get());
+        });
+        window.setOnMousePressed(pressEvent -> {
+            alertX.set(window.getX() - pressEvent.getSceneX());
+            alertY.set(window.getY() - pressEvent.getSceneY());
+        });
+
+        enDecryptError.show();
+    }
+}
diff --git a/src/org/blueshard/cryptogx/SecureDelete.java b/src/org/blueshard/cryptogx/SecureDelete.java
new file mode 100644
index 0000000..6b3a49e
--- /dev/null
+++ b/src/org/blueshard/cryptogx/SecureDelete.java
@@ -0,0 +1,196 @@
+package org.blueshard.cryptogx;
+
+import java.io.*;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.Random;
+
+public class SecureDelete {
+
+    /**
+     * <p>Overwrites the file {@param iterations} times at once with random bytes an delete it</p>
+     *
+     * @see SecureDelete#deleteFileAllInOne(File, int)
+     */
+    public static boolean deleteFileAllInOne(String filename, int iterations) throws IOException, NoSuchAlgorithmException {
+        return deleteFileAllInOne(new File(filename), iterations);
+    }
+
+    /**
+     * <p>Overwrites the file {@param iterations} times at once with random bytes and delete it</p>
+     *
+     * @param file that should be deleted
+     * @param iterations how many times the file should be overwritten before it gets deleted
+     * @return if the file could be deleted
+     * @throws IOException
+     * @throws NoSuchAlgorithmException
+     */
+    public static boolean deleteFileAllInOne(File file, int iterations) throws IOException, NoSuchAlgorithmException {
+        long fileLength = file.length() + 1 ;
+        for (int i=0; i<iterations; i++) {
+            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file));
+            if (fileLength > 1000000000) {
+                int numOfByteArrays = (int) Math.ceil((double) fileLength / 1000000000);
+                for (int len=0; len<numOfByteArrays; len++) {
+                    int newMaxFileSize = (int) fileLength / numOfByteArrays;
+                    int newMinFileSize = 0;
+                    byte[] randomBytes = new byte[new Random().nextInt(newMaxFileSize - newMinFileSize) + newMinFileSize];
+                    SecureRandom.getInstanceStrong().nextBytes(randomBytes);
+                    bufferedOutputStream.write(randomBytes);
+                }
+            } else {
+                byte[] randomBytes = new byte[new Random().nextInt((int) fileLength)];
+                SecureRandom.getInstanceStrong().nextBytes(randomBytes);
+                bufferedOutputStream.write(randomBytes);
+            }
+            bufferedOutputStream.flush();
+            bufferedOutputStream.close();
+        }
+
+        return file.delete();
+    }
+
+    /**
+     * <p>Overwrites the file {@param iterations} times at once with random bytes (minimal size {@param minFileSize}; maximal size {@param maxFileSize}) and delete it</p>
+     *
+     * @see SecureDelete#deleteFileAllInOne(String, int, long, long)
+     */
+    public static boolean deleteFileAllInOne(String filename, int iterations, long minFileSize, long maxFileSize) throws IOException, NoSuchAlgorithmException {
+        return deleteFileAllInOne(new File(filename), iterations, minFileSize, maxFileSize);
+    }
+
+    /**
+     * <p>Overwrites the file {@param iterations} times at once with random bytes (minimal size {@param minFileSize}; maximal size {@param maxFileSize}) and delete it</p>
+     *
+     * @param file that should be deleted
+     * @param iterations how many times the file should be overwritten before it gets deleted
+     * @param minFileSize is the minimal file size for every {@param iterations}
+     * @param maxFileSize is the maximal file size for every {@param iterations}
+     * @return if the file could be deleted
+     * @throws IOException
+     * @throws NoSuchAlgorithmException
+     */
+    public static boolean deleteFileAllInOne(File file, int iterations, long minFileSize, long maxFileSize) throws IOException, NoSuchAlgorithmException {
+        for (int i = 0; i < iterations; i++) {
+            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file));
+            if (maxFileSize > 1000000000) {
+                int numOfByteArrays = (int) Math.ceil((double) maxFileSize / 1000000000);
+                for (int len = 0; len < numOfByteArrays; len++) {
+                    int newMaxFileSize = (int) maxFileSize / numOfByteArrays;
+                    int newMinFileSize = 0;
+                    if (minFileSize != 0) {
+                        newMinFileSize = (int) minFileSize / numOfByteArrays;
+                    }
+                    byte[] randomBytes = new byte[new Random().nextInt(newMaxFileSize - newMinFileSize) + newMinFileSize];
+                    SecureRandom.getInstanceStrong().nextBytes(randomBytes);
+                    bufferedOutputStream.write(randomBytes);
+                }
+            } else {
+                byte[] randomBytes = new byte[new Random().nextInt((int) maxFileSize - (int) minFileSize) + (int) minFileSize];
+                SecureRandom.getInstanceStrong().nextBytes(randomBytes);
+                bufferedOutputStream.write(randomBytes);
+            }
+            bufferedOutputStream.flush();
+            bufferedOutputStream.close();
+        }
+
+        return file.delete();
+    }
+
+    /**
+     * <p>Overwrites the file {@param iterations} times line by line with random bytes and delete it</p>
+     *
+     * @see SecureDelete#deleteFileLineByLine(File, int)
+     */
+    public static boolean deleteFileLineByLine(String filename, int iterations) throws NoSuchAlgorithmException, IOException {
+        return deleteFileLineByLine(new File(filename), iterations);
+    }
+
+    /**
+     * <p>Overwrites the file {@param iterations} times line by line with random bytes and delete it</p>
+     *
+     * @param file that should be deleted
+     * @param iterations how many times the file should be overwritten before it gets deleted
+     * @return if the file could be deleted
+     * @throws IOException
+     * @throws NoSuchAlgorithmException
+     */
+    public static boolean deleteFileLineByLine(File file, int iterations) throws NoSuchAlgorithmException, IOException {
+        long fileLength = file.length() + 1 ;
+        for (int i=0; i<iterations; i++) {
+            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file));
+            if (fileLength > 1000000000) {
+                int numOfByteArrays = (int) Math.ceil((double) fileLength / 1000000000);
+                for (int len=0; len<numOfByteArrays; len++) {
+                    int newMaxFileSize = (int) fileLength / numOfByteArrays;
+                    int newMinFileSize = 0;
+                    byte[] randomBytes = new byte[new Random().nextInt(newMaxFileSize - newMinFileSize) + newMinFileSize];
+                    SecureRandom.getInstanceStrong().nextBytes(randomBytes);
+                    for (byte b: randomBytes) {
+                        bufferedOutputStream.write(b);
+                    }
+                }
+            } else {
+                byte[] randomBytes = new byte[new Random().nextInt((int) fileLength)];
+                SecureRandom.getInstanceStrong().nextBytes(randomBytes);
+                for (byte b : randomBytes) {
+                    bufferedOutputStream.write(b);
+                }
+            }
+            bufferedOutputStream.flush();
+            bufferedOutputStream.close();
+        }
+
+        return file.delete();
+    }
+
+    /**
+     * <p>Overwrites the file {@param iterations} times line by line with random bytes (minimal size {@param minFileSize}; maximal size {@param maxFileSize}) and delete it</p>
+     */
+    public static boolean deleteFileLineByLine(String filename, int iterations, long minFileSize, long maxFileSize) throws NoSuchAlgorithmException, IOException {
+        return deleteFileLineByLine(new File(filename), iterations, minFileSize, maxFileSize);
+    }
+
+    /**
+     * <p>Overwrites the file {@param iterations} times line by line with random bytes (minimal size {@param minFileSize}; maximal size {@param maxFileSize}) and delete it</p>
+     *
+     * @param file that should be deleted
+     * @param iterations how many times the file should be overwritten before it gets deleted
+     * @param minFileSize is the minimal file size for every {@param iterations}
+     * @param maxFileSize is the maximal file size for every {@param iterations}
+     * @return if the file could be deleted
+     * @throws IOException
+     * @throws NoSuchAlgorithmException
+     */
+    public static boolean deleteFileLineByLine(File file, int iterations, long minFileSize, long maxFileSize) throws NoSuchAlgorithmException, IOException {
+            for (int i=0; i<iterations; i++) {
+                BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file));
+                if (maxFileSize > 1000000000) {
+                    int numOfByteArrays = (int) Math.ceil((double) maxFileSize / 1000000000);
+                    for (int len=0; len<numOfByteArrays; len++) {
+                        int newMaxFileSize = (int) maxFileSize / numOfByteArrays;
+                        int newMinFileSize = 0;
+                        if (minFileSize != 0) {
+                            newMinFileSize = (int) minFileSize / numOfByteArrays;
+                        }
+                        byte[] randomBytes = new byte[new Random().nextInt(newMaxFileSize - newMinFileSize) + newMinFileSize];
+                        SecureRandom.getInstanceStrong().nextBytes(randomBytes);
+                        for (byte b: randomBytes) {
+                            bufferedOutputStream.write(b);
+                        }
+                    }
+                } else {
+                    byte[] randomBytes = new byte[new Random().nextInt((int) maxFileSize - (int) minFileSize) + (int) minFileSize];
+                    SecureRandom.getInstanceStrong().nextBytes(randomBytes);
+                    for (byte b : randomBytes) {
+                        bufferedOutputStream.write(b);
+                    }
+                }
+                bufferedOutputStream.flush();
+                bufferedOutputStream.close();
+            }
+
+        return file.delete();
+    }
+
+}
diff --git a/src/org/blueshard/cryptogx/Utils.java b/src/org/blueshard/cryptogx/Utils.java
new file mode 100644
index 0000000..6d6f73e
--- /dev/null
+++ b/src/org/blueshard/cryptogx/Utils.java
@@ -0,0 +1,21 @@
+package org.blueshard.cryptogx;
+
+public class Utils {
+
+    /**
+     * <p>Checks if any character in {@param characters} appears in {@param string}</p>
+     *
+     * @param characters that should be searched in {@param string}
+     * @param string that should be searched for the characters
+     * @return if any character in {@param characters} appears in {@param string}
+     */
+    public static boolean hasAnyCharacter(CharSequence characters, String string) {
+        for (char c: characters.toString().toCharArray()) {
+            if (string.indexOf(c) != -1) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+}
diff --git a/src/org/blueshard/cryptogx/resources/addSettingsGUI.fxml b/src/org/blueshard/cryptogx/resources/addSettingsGUI.fxml
new file mode 100644
index 0000000..5d8b7d4
--- /dev/null
+++ b/src/org/blueshard/cryptogx/resources/addSettingsGUI.fxml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.scene.control.Accordion?>
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.control.CheckBox?>
+<?import javafx.scene.control.ComboBox?>
+<?import javafx.scene.control.MenuBar?>
+<?import javafx.scene.control.PasswordField?>
+<?import javafx.scene.control.Separator?>
+<?import javafx.scene.control.TextField?>
+<?import javafx.scene.control.TitledPane?>
+<?import javafx.scene.image.Image?>
+<?import javafx.scene.image.ImageView?>
+<?import javafx.scene.layout.AnchorPane?>
+<?import javafx.scene.text.Text?>
+
+<AnchorPane fx:id="rootWindow" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="605.0" prefWidth="320.0" style="-fx-border-color: black;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <MenuBar fx:id="menuBar" prefHeight="25.0" prefWidth="320.0" style="-fx-border-color: black;" />
+      <ImageView fx:id="closeButton" fitHeight="25.0" fitWidth="25.0" layoutX="295.0" pickOnBounds="true" preserveRatio="true">
+         <image>
+            <Image url="@close.png" />
+         </image>
+      </ImageView>
+      <Text fx:id="saveSettingsText" layoutX="125.0" layoutY="46.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Save settings" />
+      <Text fx:id="nameOfSettingText" layoutX="77.0" layoutY="86.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Name of the new configuration" />
+      <TextField fx:id="settingsNameEntry" layoutX="27.0" layoutY="101.0" prefHeight="25.0" prefWidth="264.0" />
+      <Accordion fx:id="rootAccordion" layoutX="10.0" layoutY="150.0" prefHeight="280.0" prefWidth="300.0">
+        <panes>
+          <TitledPane fx:id="textEnDecryptRoot" animated="false" text="Text en - / decrypt">
+            <content>
+              <AnchorPane fx:id="textEnDecryptPane" minHeight="0.0" minWidth="0.0" prefWidth="200.0">
+                     <children>
+                        <Text fx:id="textKeyText" layoutX="10.0" layoutY="40.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Key" />
+                        <TextField fx:id="textKeyEntry" layoutX="85.0" layoutY="23.0" prefHeight="25.0" prefWidth="175.0" />
+                        <Text fx:id="textSaltText" layoutX="10.0" layoutY="90.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Salt" />
+                        <TextField fx:id="textSaltEntry" layoutX="85.0" layoutY="73.0" prefHeight="25.0" prefWidth="175.0" />
+                        <Text fx:id="textAlgorithmText" layoutX="10.0" layoutY="140.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Algorithm" />
+                        <ComboBox fx:id="textAlgorithmComboBox" layoutX="85.0" layoutY="123.0" prefHeight="25.0" prefWidth="175.0" />
+                     </children>
+                  </AnchorPane>
+            </content>
+          </TitledPane>
+          <TitledPane fx:id="fileEnDecryptRoot" animated="false" text="File en- / decrypt">
+               <content>
+                  <AnchorPane fx:id="fileEnDecryptPane" minHeight="0.0" minWidth="0.0" prefWidth="200.0">
+                     <children>
+                        <Text fx:id="fileEnDecryptKeyText" layoutX="10.0" layoutY="40.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Key" />
+                        <TextField fx:id="fileEnDecryptKeyEntry" layoutX="85.0" layoutY="23.0" prefHeight="25.0" prefWidth="175.0" />
+                        <Text fx:id="fileEnDecryptSaltText" layoutX="10.0" layoutY="90.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Salt" />
+                        <TextField fx:id="fileEnDecryptSaltEntry" layoutX="85.0" layoutY="73.0" prefHeight="25.0" prefWidth="175.0" />
+                        <Text fx:id="fileEnDecryptAlgorithmText" layoutX="10.0" layoutY="140.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Algorithm" />
+                        <ComboBox fx:id="fileEnDecryptAlgorithmComboBox" layoutX="85.0" layoutY="123.0" prefHeight="25.0" prefWidth="175.0" />
+                     </children>
+                  </AnchorPane>
+               </content>
+          </TitledPane>
+          <TitledPane fx:id="fileDeleteRoot" animated="false" text="Secure delete files">
+            <content>
+              <AnchorPane fx:id="fileDeletePane" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
+                     <children>
+                        <Text fx:id="fileDeleteIterationsText" layoutX="14.0" layoutY="94.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Iterations" />
+                        <TextField fx:id="fileDeleteIterationsEntry" layoutX="85.0" layoutY="77.0" prefHeight="25.0" prefWidth="175.0" />
+                     </children>
+                  </AnchorPane>
+            </content>
+          </TitledPane>
+            <TitledPane fx:id="settingsRoot" animated="false" text="Settings">
+              <content>
+                <AnchorPane fx:id="settingsPane" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
+                     <children>
+                        <Text fx:id="fileOutputPathText" layoutX="10.0" layoutY="27.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Default file output path" />
+                        <TextField fx:id="fileOutputPathEntry" layoutX="10.0" layoutY="41.0" prefHeight="25.0" prefWidth="280.0" />
+                        <Button fx:id="fileOutputPathButton" layoutX="85.0" layoutY="78.0" mnemonicParsing="false" text="Change output path" />
+                        <CheckBox fx:id="removeFromFileBoxCheckBox" layoutX="10.0" layoutY="121.0" mnemonicParsing="false" text="Remove files from filebox after en- / decryption" />
+                        <CheckBox fx:id="limitNumberOfThreadsCheckBox" layoutX="10.0" layoutY="151.0" mnemonicParsing="false" text="Limit number of threads" />
+                     </children>
+                  </AnchorPane>
+              </content>
+            </TitledPane>
+        </panes>
+      </Accordion>
+      <CheckBox fx:id="encryptSettings" layoutX="10.0" layoutY="447.0" mnemonicParsing="false" text="Encrypt settings" />
+      <Separator fx:id="separator1" layoutX="10.0" layoutY="474.0" prefWidth="300.0" />
+      <PasswordField fx:id="hiddenPasswordEntry" disable="true" layoutX="10.0" layoutY="490.0" prefHeight="25.0" prefWidth="300.0" promptText="Password" />
+      <TextField fx:id="showedPasswordEntry" disable="true" layoutX="10.0" layoutY="490.0" prefHeight="25.0" prefWidth="300.0" promptText="Password" visible="false" />
+      <CheckBox fx:id="showPassword" disable="true" layoutX="10.0" layoutY="525.0" mnemonicParsing="false" text="Show password" />
+      <Separator fx:id="separator2" layoutX="10.0" layoutY="551.0" prefWidth="300.0" />
+      <Button fx:id="saveButton" layoutX="131.0" layoutY="564.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="56.0" text="Save" />
+   </children>
+</AnchorPane>
diff --git a/src/org/blueshard/cryptogx/resources/close.png b/src/org/blueshard/cryptogx/resources/close.png
new file mode 100644
index 0000000000000000000000000000000000000000..1113eafd348d9b058f08e335d86fcea4d48e3946
GIT binary patch
literal 14702
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

literal 0
HcmV?d00001

diff --git a/src/org/blueshard/cryptogx/resources/cryptoGX.png b/src/org/blueshard/cryptogx/resources/cryptoGX.png
new file mode 100644
index 0000000000000000000000000000000000000000..f84ad554dda852f1223c06333f7a9226071e505b
GIT binary patch
literal 51400
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%0AN=LaQB=3_H?
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

literal 0
HcmV?d00001

diff --git a/src/org/blueshard/cryptogx/resources/exportSettingsGUI.fxml b/src/org/blueshard/cryptogx/resources/exportSettingsGUI.fxml
new file mode 100644
index 0000000..f40bf75
--- /dev/null
+++ b/src/org/blueshard/cryptogx/resources/exportSettingsGUI.fxml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.control.MenuBar?>
+<?import javafx.scene.control.ScrollPane?>
+<?import javafx.scene.image.Image?>
+<?import javafx.scene.image.ImageView?>
+<?import javafx.scene.layout.AnchorPane?>
+<?import javafx.scene.layout.VBox?>
+<?import javafx.scene.text.Text?>
+
+<AnchorPane fx:id="mainWindow" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="253.0" prefWidth="254.0" style="-fx-border-color: black;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <MenuBar fx:id="menuBar" prefHeight="25.0" prefWidth="254.0" style="-fx-border-color: black;" />
+      <ImageView fx:id="closeButton" fitHeight="25.0" fitWidth="25.0" layoutX="228.0" layoutY="1.0" pickOnBounds="true" preserveRatio="true">
+         <image>
+            <Image url="@close.png" />
+         </image>
+      </ImageView>
+      <Text fx:id="exportSettingsText" layoutX="88.0" layoutY="48.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Export settings" />
+      <ScrollPane layoutX="7.0" layoutY="64.0" prefHeight="120.0" prefWidth="240.0">
+         <content>
+            <VBox fx:id="settingsBox" prefHeight="118.0" prefWidth="238.0" />
+         </content>
+      </ScrollPane>
+      <Button fx:id="exportButton" layoutX="98.0" layoutY="203.0" mnemonicParsing="false" text="Export..." />
+   </children>
+</AnchorPane>
diff --git a/src/org/blueshard/cryptogx/resources/loadSettingsGUI.fxml b/src/org/blueshard/cryptogx/resources/loadSettingsGUI.fxml
new file mode 100644
index 0000000..df7f741
--- /dev/null
+++ b/src/org/blueshard/cryptogx/resources/loadSettingsGUI.fxml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.scene.control.*?>
+<?import javafx.scene.image.*?>
+<?import javafx.scene.layout.*?>
+<?import javafx.scene.text.*?>
+
+<AnchorPane fx:id="rootWindow" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="235.0" prefWidth="242.0" style="-fx-border-color: black;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <MenuBar fx:id="menuBar" prefHeight="25.0" prefWidth="242.0" style="-fx-border-color: black;" />
+      <ImageView fx:id="closeButton" fitHeight="25.0" fitWidth="25.0" layoutX="217.0" pickOnBounds="true" preserveRatio="true">
+         <image>
+            <Image url="@close.png" />
+         </image>
+      </ImageView>
+      <Text fx:id="loadSettingsText" layoutX="86.0" layoutY="50.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Load settings" />
+      <ComboBox fx:id="settingsBox" layoutX="24.0" layoutY="72.0" prefHeight="25.0" prefWidth="194.0" />
+      <Text fx:id="passwordText" layoutX="14.0" layoutY="136.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Password" />
+      <PasswordField fx:id="passwordEntryHide" layoutX="79.0" layoutY="119.0" />
+      <TextField fx:id="passwordEntryShow" layoutX="79.0" layoutY="119.0" visible="false" />
+      <CheckBox fx:id="showPassword" layoutX="14.0" layoutY="154.0" mnemonicParsing="false" text="Show password" />
+      <Separator fx:id="separator1" layoutX="16.0" layoutY="181.0" prefHeight="0.0" prefWidth="211.0" />
+      <Button fx:id="loadButton" layoutX="29.0" layoutY="193.0" mnemonicParsing="false" text="Load" />
+      <Button fx:id="deleteButton" layoutX="162.0" layoutY="193.0" mnemonicParsing="false" text="Delete" />
+   </children>
+</AnchorPane>
diff --git a/src/org/blueshard/cryptogx/resources/loading.gif b/src/org/blueshard/cryptogx/resources/loading.gif
new file mode 100644
index 0000000000000000000000000000000000000000..a3ba16a5c19b84c0d0721b350fa003543da29cc7
GIT binary patch
literal 9270
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
CwGGk$

literal 0
HcmV?d00001

diff --git a/src/org/blueshard/cryptogx/resources/mainGUI.fxml b/src/org/blueshard/cryptogx/resources/mainGUI.fxml
new file mode 100644
index 0000000..39dbbe8
--- /dev/null
+++ b/src/org/blueshard/cryptogx/resources/mainGUI.fxml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.control.ComboBox?>
+<?import javafx.scene.control.Menu?>
+<?import javafx.scene.control.MenuBar?>
+<?import javafx.scene.control.MenuItem?>
+<?import javafx.scene.control.RadioMenuItem?>
+<?import javafx.scene.control.ScrollPane?>
+<?import javafx.scene.control.Separator?>
+<?import javafx.scene.control.SeparatorMenuItem?>
+<?import javafx.scene.control.TextArea?>
+<?import javafx.scene.control.TextField?>
+<?import javafx.scene.image.Image?>
+<?import javafx.scene.image.ImageView?>
+<?import javafx.scene.layout.AnchorPane?>
+<?import javafx.scene.layout.VBox?>
+<?import javafx.scene.text.Text?>
+
+<AnchorPane fx:id="rootWindow" prefHeight="470.0" prefWidth="900.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.blueshard.cryptogx.Controller">
+   <children>
+      <MenuBar fx:id="menubar" prefHeight="25.0" prefWidth="900.0">
+         <menus>
+            <Menu fx:id="fileMenu" mnemonicParsing="false" text="File">
+              <items>
+                  <MenuItem fx:id="fileMenuClose" mnemonicParsing="false" onAction="#closeApplication" text="Exit" />
+              </items>
+            </Menu>
+            <Menu fx:id="settingsMenu" mnemonicParsing="false" text="Settings">
+               <items>
+                  <MenuItem fx:id="setDefaultOutputPath" mnemonicParsing="false" text="Set default file en- / decryption output path..." />
+                  <RadioMenuItem fx:id="removeFileFromFileBox" mnemonicParsing="false" text="Remove files from filebox after en- / decryption" />
+                  <RadioMenuItem fx:id="limitNumberOfThreads" mnemonicParsing="false" selected="true" text="Limit number of threads" />
+                  <SeparatorMenuItem fx:id="settingsSeparator1" mnemonicParsing="false" />
+                  <MenuItem fx:id="saveSettings" mnemonicParsing="false" text="Save settings..." />
+                  <MenuItem fx:id="loadSettings" disable="true" mnemonicParsing="false" text="Load settings..." />
+                  <MenuItem fx:id="exportSettings" disable="true" mnemonicParsing="false" text="Export settings..." />
+                  <MenuItem fx:id="importSettings" mnemonicParsing="false" text="Import settings..." />
+               </items></Menu>
+            <Menu fx:id="helpMenu" mnemonicParsing="false" text="Help" />
+         </menus>
+      </MenuBar>
+      <ImageView fx:id="minimizeWindow" fitHeight="25.0" fitWidth="25.0" layoutX="850.0" onMouseClicked="#minimizeApplication" pickOnBounds="true" preserveRatio="true">
+         <image>
+            <Image url="@minimize.png" />
+         </image></ImageView>
+      <ImageView fx:id="closeWindow" fitHeight="25.0" fitWidth="25.0" layoutX="875.0" onMouseClicked="#closeApplication" pickOnBounds="true" preserveRatio="true">
+         <image>
+            <Image url="@close.png" />
+         </image></ImageView>
+      <Text fx:id="textText" layoutX="103.0" layoutY="50.0" strokeType="OUTSIDE" strokeWidth="0.0" text="En- / decrypt Text" />
+      <TextField fx:id="textKeyEntry" layoutX="76.0" layoutY="64.0" onKeyTyped="#keyTypedTooltip" onMouseExited="#mouseExitEntryTooltip" onMouseMoved="#mouseOverEntryTooltip" promptText="Key" />
+      <TextArea fx:id="textDecryptedEntry" layoutX="7.0" layoutY="107.0" onKeyTyped="#keyTypedTooltip" prefHeight="105.0" prefWidth="286.0" promptText="Decrypted Text" />
+      <TextArea fx:id="textEncryptedEntry" layoutX="7.0" layoutY="222.0" onKeyTyped="#keyTypedTooltip" prefHeight="105.0" prefWidth="286.0" promptText="Encrypted Text" />
+      <Button fx:id="textEncryptButton" layoutX="47.0" layoutY="339.0" mnemonicParsing="false" onAction="#textEncryptButton" text="Encrypt" />
+      <ImageView fx:id="textLoadingImage" fitHeight="40.0" fitWidth="40.0" layoutX="131.0" layoutY="332.0" pickOnBounds="true" preserveRatio="true" />
+      <Button fx:id="textDecryptButton" layoutX="199.0" layoutY="340.0" mnemonicParsing="false" onAction="#textDecryptButton" text="Decrypt" />
+      <Separator fx:id="textSeparator1" layoutX="7.0" layoutY="379.0" prefHeight="8.0" prefWidth="109.0" />
+      <Text fx:id="textAdvanced" layoutX="124.0" layoutY="386.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Advanced" wrappingWidth="53.701171875" />
+      <Separator fx:id="textSeparator2" layoutX="187.0" layoutY="379.0" prefHeight="8.0" prefWidth="109.0" />
+      <Text fx:id="textAlgorithm" layoutX="194.0" layoutY="409.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Algorithm" />
+      <TextField fx:id="textSaltEntry" layoutX="14.0" layoutY="419.0" onKeyTyped="#keyTypedTooltip" onMouseExited="#mouseExitEntryTooltip" onMouseMoved="#mouseOverEntryTooltip" prefHeight="25.0" prefWidth="136.0" promptText="Salt" />
+      <ComboBox fx:id="textAlgorithmBox" layoutX="156.0" layoutY="419.0" prefHeight="25.0" prefWidth="136.0" />
+      <Separator fx:id="midSeparator1" layoutX="300.0" layoutY="35.0" orientation="VERTICAL" prefHeight="424.0" prefWidth="0.0" />
+      <Text fx:id="fileEnDecryptText" layoutX="403.0" layoutY="50.0" strokeType="OUTSIDE" strokeWidth="0.0" text="En- / decrypt Files" />
+      <TextField fx:id="fileEnDecryptKeyEntry" layoutX="376.0" layoutY="64.0" onKeyTyped="#keyTypedTooltip" onMouseExited="#mouseExitEntryTooltip" onMouseMoved="#mouseOverEntryTooltip" promptText="Key" />
+      <Button fx:id="fileEnDecryptFilesButton" layoutX="408.0" layoutY="97.0" mnemonicParsing="false" onAction="#fileEnDecryptChoose" text="Choose files..." />
+      <ScrollPane fx:id="fileEnDecryptInputScroll" hbarPolicy="NEVER" layoutX="309.0" layoutY="130.0" onKeyPressed="#onFileEnDecryptPaste" prefHeight="107.0" prefWidth="286.0">
+         <content>
+            <VBox fx:id="fileEnDecryptInputFiles" onDragDropped="#onFileEnDecryptDragNDrop" onDragOver="#onFileEnDecryptDragOver" prefHeight="105.0" prefWidth="282.0" />
+         </content>
+      </ScrollPane>
+      <Text fx:id="fileEncryptOutputFileText" layoutX="310.0" layoutY="261.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Encrypted File" />
+      <TextField fx:id="fileEncryptOutputFile" editable="false" layoutX="390.0" layoutY="244.0" onKeyTyped="#keyTypedTooltip" onMouseExited="#mouseExitEntryTooltip" onMouseMoved="#mouseOverEntryTooltip" prefHeight="25.0" prefWidth="201.0" />
+      <Text fx:id="fileDecryptOutputFileText" layoutX="310.0" layoutY="290.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Decrypted File" />
+      <TextField fx:id="fileDecryptOutputFile" editable="false" layoutX="390.0" layoutY="273.0" onKeyTyped="#keyTypedTooltip" onMouseExited="#mouseExitEntryTooltip" onMouseMoved="#mouseOverEntryTooltip" prefHeight="25.0" prefWidth="201.0" />
+      <Button fx:id="fileEncrypt" layoutX="347.0" layoutY="313.0" mnemonicParsing="false" onAction="#fileEncryptButton" text="Encrypt" />
+      <ImageView fx:id="fileEnDecryptLoadingImage" fitHeight="40.0" fitWidth="40.0" layoutX="432.0" layoutY="306.0" pickOnBounds="true" preserveRatio="true" />
+      <Button fx:id="fileDecrypt" layoutX="499.0" layoutY="313.0" mnemonicParsing="false" onAction="#fileDecryptButton" text="Decrypt" />
+      <Button fx:id="fileEnDecryptStop" layoutX="426.0" layoutY="346.0" mnemonicParsing="false" onAction="#fileEnDecryptCancelButton" text="Cancel" />
+      <Separator fx:id="fileEnDecryptSeparator1" layoutX="309.0" layoutY="379.0" prefHeight="8.0" prefWidth="109.0" />
+      <Text fx:id="fileEnDecryptAdvanced" layoutX="426.0" layoutY="386.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Advanced" wrappingWidth="53.701171875" />
+      <Separator fx:id="fileEnDecryptSeparator2" layoutX="485.0" layoutY="379.0" prefHeight="8.0" prefWidth="109.0" />
+      <Text fx:id="fileEnDecryptAlgorithm" layoutX="494.0" layoutY="409.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Algorithm" />
+      <TextField fx:id="fileEnDecryptSaltEntry" layoutX="311.0" layoutY="419.0" onKeyTyped="#keyTypedTooltip" onMouseExited="#mouseExitEntryTooltip" onMouseMoved="#mouseOverEntryTooltip" prefHeight="25.0" prefWidth="136.0" promptText="Salt" />
+      <ComboBox fx:id="fileEnDecryptAlgorithmBox" layoutX="455.0" layoutY="419.0" prefHeight="25.0" prefWidth="136.0" />
+      <Separator fx:id="midSeparator2" layoutX="600.0" layoutY="35.0" orientation="VERTICAL" prefHeight="424.0" prefWidth="0.0" />
+      <Text fx:id="fileDeleteText" layoutX="703.0" layoutY="50.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Secure delete files" />
+      <Button fx:id="fileEnDecryptFilesButton1" layoutX="708.0" layoutY="64.0" mnemonicParsing="false" onAction="#fileDeleteChoose" text="Choose files..." />
+      <ScrollPane fx:id="fileDeleteInputScroll" hbarPolicy="NEVER" layoutX="608.0" layoutY="96.0" prefHeight="228.0" prefWidth="285.0">
+         <content>
+            <VBox fx:id="fileDeleteInputFiles" onDragDropped="#onFileDeleteDragNDrop" onDragOver="#onFileDeleteDragOver" prefHeight="226.0" prefWidth="282.0" />
+         </content>
+      </ScrollPane>
+      <Button fx:id="fileDeleteButton" layoutX="647.0" layoutY="339.0" mnemonicParsing="false" onAction="#fileDelete" text="Delete" />
+      <ImageView fx:id="fileDeleteLoadingImage" fitHeight="40.0" fitWidth="40.0" layoutX="729.0" layoutY="332.0" pickOnBounds="true" preserveRatio="true" />
+      <Button fx:id="fileDeleteStop" layoutX="799.0" layoutY="339.0" mnemonicParsing="false" onAction="#fileDeleteCancelButton" text="Cancel" />
+      <Separator fx:id="fileDeleteSeparator1" layoutX="610.0" layoutY="379.0" prefHeight="8.0" prefWidth="109.0" />
+      <Text fx:id="fileDeleteAdvanced" layoutX="725.0" layoutY="386.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Advanced" wrappingWidth="53.015625" />
+      <Separator fx:id="fileDeleteSeparator2" layoutX="781.0" layoutY="379.0" prefHeight="8.0" prefWidth="109.0" />
+      <TextField fx:id="fileDeleteIterationsEntry" layoutX="684.0" layoutY="419.0" onKeyTyped="#keyTypedTooltip" onMouseExited="#mouseExitEntryTooltip" onMouseMoved="#mouseOverEntryTooltip" prefHeight="25.0" prefWidth="136.0" promptText="Iterations" text="5" />
+   </children>
+</AnchorPane>
diff --git a/src/org/blueshard/cryptogx/resources/minimize.png b/src/org/blueshard/cryptogx/resources/minimize.png
new file mode 100644
index 0000000000000000000000000000000000000000..928735e7810c0c12285d774a3c883e39cfad719a
GIT binary patch
literal 14698
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

literal 0
HcmV?d00001