| @@ -5,37 +5,51 @@ package de.uniluebeck.mi.projmi6.controller; | |||
| */ | |||
| import de.uniluebeck.mi.projmi6.Main; | |||
| import javafx.beans.binding.Bindings; | |||
| import javafx.fxml.FXML; | |||
| import javafx.scene.control.Alert; | |||
| import javafx.scene.control.Button; | |||
| import javafx.scene.control.TextField; | |||
| import javafx.scene.control.TextFormatter; | |||
| import java.net.Inet4Address; | |||
| import java.net.Inet6Address; | |||
| import java.net.InetAddress; | |||
| import java.net.UnknownHostException; | |||
| import java.util.regex.Pattern; | |||
| /** | |||
| * The controller for the settings under the settings tab. | |||
| * Contains only OPS server ip settings. | |||
| */ | |||
| public class SettingsController { | |||
| /** | |||
| * A pointer to the applications main controller | |||
| */ | |||
| private MainController mainController; | |||
| /** | |||
| * Constructor - The object is generated in the MainController. | |||
| * @param mainController The MainController that generates this object. | |||
| */ | |||
| public SettingsController (MainController mainController){ | |||
| this.mainController = mainController; | |||
| } | |||
| /** | |||
| * The button that for saving the data in the text fields. | |||
| */ | |||
| @FXML | |||
| private Button opsServerSave; | |||
| /** | |||
| * The TextFields for entering IP-address and portnumber for the OPS-server. | |||
| */ | |||
| @FXML | |||
| private TextField opsServerIp, opsServerPort; | |||
| /** | |||
| * initialize()-method for the FXMLLoader. | |||
| */ | |||
| @FXML | |||
| private void initialize(){ | |||
| opsServerIp.setText(Main.OPS_IP); | |||
| @@ -53,9 +67,13 @@ public class SettingsController { | |||
| alert.showAndWait(); | |||
| } | |||
| }); | |||
| } | |||
| /** | |||
| * Validation error dialog. | |||
| * @param title The dialogs header text. | |||
| * @param message The dialogs content text. | |||
| */ | |||
| private void showMessage(String title, String message) { | |||
| Alert alert = new Alert(Alert.AlertType.INFORMATION); | |||
| alert.setTitle("Ung\u00fcltige Daten!"); | |||
| @@ -66,7 +84,15 @@ public class SettingsController { | |||
| } | |||
| private boolean validateData(String server, String portStr){ | |||
| /** | |||
| * Checks if the OPS-servers IP address and portnumber are valid, | |||
| * shows error messages if not. | |||
| * | |||
| * @param serverIp The servers ip address as string | |||
| * @param portStr The port number as string | |||
| * @return true if serverIp is a valid ip and portStr a valid port number | |||
| */ | |||
| private boolean validateData(String serverIp, String portStr){ | |||
| int port = -1; | |||
| try{ | |||
| port = Integer.parseInt(portStr); | |||
| @@ -78,7 +104,7 @@ public class SettingsController { | |||
| showMessage("Portnummer ist nicht valide!", "Die Portnummer muss eine Zahl zwischen 1024 und 65535 sein!"); | |||
| return false; | |||
| } | |||
| if(!validate(server)){ | |||
| if(!validateIpString(serverIp)){ | |||
| showMessage("IP-Adresse nicht valide!", "Die IP-Adresse ist nicht g\u00fcltig!"); | |||
| return false; | |||
| } | |||
| @@ -86,13 +112,22 @@ public class SettingsController { | |||
| return true; | |||
| } | |||
| /** | |||
| * Regex for the {@link #validateIpString(String)} method. | |||
| */ | |||
| private static final Pattern PATTERN = Pattern.compile( | |||
| "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + | |||
| "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + | |||
| "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + | |||
| "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$"); | |||
| public static boolean validate(final String ip) { | |||
| /** | |||
| * Checks if the given string is a ip address string. | |||
| * | |||
| * @param ip The string to be validated. | |||
| * @return true if ip is a valid ip address, otherwise false | |||
| */ | |||
| public static boolean validateIpString(final String ip) { | |||
| return PATTERN.matcher(ip).matches(); | |||
| } | |||
| @@ -25,19 +25,21 @@ import java.util.List; | |||
| import java.util.stream.Collectors; | |||
| /** | |||
| * Created by 631806 on 12.11.15. | |||
| * The controller class for the hospital ward history. | |||
| * | |||
| * Created by Johannes on 12.11.15. | |||
| */ | |||
| public class StationsHistorieController { | |||
| @FXML | |||
| public Button btnStatHistAbort; | |||
| SimpleObjectProperty<State> state = new SimpleObjectProperty<>(State.VIEW); | |||
| private Button btnStatHistAbort; | |||
| private final SimpleObjectProperty<State> state = new SimpleObjectProperty<>(State.VIEW); | |||
| @FXML | |||
| GridPane fields; | |||
| private GridPane fields; | |||
| @FXML | |||
| Button btnStatHistEdit; | |||
| private Button btnStatHistEdit; | |||
| @FXML | |||
| Button btnStatHistDelete; | |||
| private Button btnStatHistDelete; | |||
| /** | |||
| * The station history that is shown in the edit window, or null if a new station history should be created. | |||
| */ | |||
| @@ -22,8 +22,15 @@ import javafx.scene.text.Text; | |||
| import java.sql.SQLException; | |||
| /** | |||
| * Controller for the list of examinations. | |||
| */ | |||
| public class UntersuchungenController { | |||
| /** | |||
| * The states the controller might be. | |||
| */ | |||
| public enum State { | |||
| CREATE, EDIT, VIEW | |||
| } | |||
| @@ -31,44 +38,40 @@ public class UntersuchungenController { | |||
| private final SimpleObjectProperty<State> state = new SimpleObjectProperty<>(State.VIEW); | |||
| /** | |||
| * A getter for the {@link #stateProperty()}. | |||
| * @return The controllers current state | |||
| */ | |||
| public State getState() { | |||
| return state.get(); | |||
| } | |||
| /** | |||
| * A property for the state of the controller/UI. | |||
| * @return | |||
| */ | |||
| public ReadOnlyObjectProperty<State> stateProperty() { | |||
| return state; | |||
| } | |||
| /** | |||
| * The list of examinations that is shown in the views that belong to the controller. | |||
| */ | |||
| private SimpleObjectProperty<ObservableList<Untersuchung>> untersuchungen = new SimpleObjectProperty<>(); | |||
| /** | |||
| * A pointer to the main controller. | |||
| */ | |||
| private MainController mainController; | |||
| @FXML | |||
| private Button btnUntsCancel; | |||
| @FXML | |||
| private Button btnUntsCreate; | |||
| private Button btnUntsCancel, btnUntsCreate, btnUntsSave, btnUntsAbort; | |||
| @FXML | |||
| private DateTimePicker dtTmUntersuchungszeitpunkt; | |||
| @FXML | |||
| private Button btnUntsSave; | |||
| @FXML | |||
| private Label untsChanger; | |||
| @FXML | |||
| private Label untsCreator; | |||
| @FXML | |||
| private Label untsChangeTime; | |||
| @FXML | |||
| private Label untsCreateTime; | |||
| private Label untsChanger, untsCreator, untsChangeTime, untsCreateTime; | |||
| @FXML | |||
| private ListView<Untersuchung> untsList; | |||
| @@ -76,38 +79,58 @@ public class UntersuchungenController { | |||
| @FXML | |||
| private ComboBox<OpsCode> untsOpsCode; | |||
| @FXML | |||
| private GridPane fields; | |||
| @FXML | |||
| private ComboBox<Mitarbeiter> untsArzt; | |||
| /** | |||
| * Constructor for the mainController. | |||
| * @param mainController The MainController that created this instance. | |||
| */ | |||
| public UntersuchungenController(MainController mainController) { | |||
| this.mainController = mainController; | |||
| } | |||
| /** | |||
| * A getter for the {@link #untersuchungenProperty()}. Might be null. | |||
| * @return The list of examinations that are shown in this view. | |||
| */ | |||
| public ObservableList<Untersuchung> getUntersuchungen() { | |||
| return untersuchungen.get(); | |||
| } | |||
| /** | |||
| * A setter for the {@link #untersuchungenProperty()}. Might be null. | |||
| * @param untersuchungen The ObservableList to set. | |||
| */ | |||
| public void setUntersuchungen(ObservableList<Untersuchung> untersuchungen) { | |||
| this.untersuchungen.set(untersuchungen); | |||
| } | |||
| /** | |||
| * The property for the observable list of examinations for the current patient. | |||
| */ | |||
| public SimpleObjectProperty<ObservableList<Untersuchung>> untersuchungenProperty() { | |||
| return untersuchungen; | |||
| } | |||
| /** | |||
| * Initializes the comboboxes with values. | |||
| */ | |||
| private void initComboBoxes(){ | |||
| untsOpsCode.itemsProperty().bind(mainController.getStammdaten().opsCodesProperty()); | |||
| new SelectKeyComboBoxListener(untsOpsCode); | |||
| untsList.itemsProperty().bind(untersuchungen); | |||
| untsArzt.itemsProperty().bind(mainController.getStammdaten().mitarbeiterProperty()); | |||
| } | |||
| /** | |||
| * Binds the buttons visibility to the controllers current state. | |||
| */ | |||
| private void initButtons(){ | |||
| btnUntsCreate.disableProperty().bind(mainController.fallProperty().isNull()); | |||
| @@ -122,33 +145,14 @@ public class UntersuchungenController { | |||
| btnUntsAbort.visibleProperty().bind(btnUntsSave.managedProperty()); | |||
| } | |||
| @FXML | |||
| private Button btnUntsAbort; | |||
| @FXML | |||
| public void initialize(){ | |||
| //Clear fields on startup | |||
| copyUntersuchungDataIntoFields(); | |||
| initComboBoxes(); | |||
| initButtons(); | |||
| /** | |||
| * Set up data, disable property and listener. | |||
| */ | |||
| private void initList(){ | |||
| untsList.itemsProperty().bind(untersuchungen); | |||
| untsList.getSelectionModel().selectedItemProperty().addListener( | |||
| (observable, oldVal, newVal) -> copyUntersuchungDataIntoFields()); | |||
| fields.disableProperty().bind(state.isEqualTo(State.VIEW)); | |||
| state.addListener((observable, oldValue, newValue) -> { | |||
| if(newValue==State.VIEW){ | |||
| mainController.unlockFromEdit(); | |||
| }else{ | |||
| mainController.lockForEdit(MainController.TabName.UNTERSUCHUNG); | |||
| } | |||
| }); | |||
| untsList.disableProperty().bind(state.isNotEqualTo(State.VIEW)); | |||
| untsList.setCellFactory(lv -> { | |||
| return new ListCell<Untersuchung>(){ | |||
| @@ -175,15 +179,44 @@ public class UntersuchungenController { | |||
| }); | |||
| } | |||
| /** | |||
| * FXMLLoaders init method. | |||
| */ | |||
| @FXML | |||
| void clickedUntsCreate() { | |||
| void initialize(){ | |||
| //Clear fields on startup | |||
| copyUntersuchungDataIntoFields(); | |||
| initComboBoxes(); | |||
| initButtons(); | |||
| initList(); | |||
| fields.disableProperty().bind(state.isEqualTo(State.VIEW)); | |||
| state.addListener((observable, oldValue, newValue) -> { | |||
| if(newValue==State.VIEW){ | |||
| mainController.unlockFromEdit(); | |||
| }else{ | |||
| mainController.lockForEdit(MainController.TabName.UNTERSUCHUNG); | |||
| } | |||
| }); | |||
| } | |||
| /** | |||
| * Handler for the new examination button. | |||
| */ | |||
| @FXML | |||
| private void clickedUntsCreate() { | |||
| this.state.set(State.CREATE); | |||
| clearFields(); | |||
| untsArzt.getSelectionModel().select(mainController.getCurrentMitarbeiter()); | |||
| } | |||
| /** | |||
| * Handler for the cancel button. | |||
| */ | |||
| @FXML | |||
| void clickedUntsCancel() { | |||
| private void clickedUntsCancel() { | |||
| Untersuchung untersuchung = untsList.getSelectionModel().getSelectedItem(); | |||
| if(untersuchung==null) { | |||
| return; | |||
| @@ -197,17 +230,20 @@ public class UntersuchungenController { | |||
| mainController.refreshCaseData(); | |||
| } | |||
| @FXML | |||
| GridPane fields; | |||
| /** | |||
| * Handler for the abort button. Aborts editing/creating. | |||
| */ | |||
| @FXML | |||
| private void clickedUntsAbort(){ | |||
| state.set(State.VIEW); | |||
| copyUntersuchungDataIntoFields(); | |||
| } | |||
| /** | |||
| * Handler for the save button. Saves the data in the fields in the database. | |||
| */ | |||
| @FXML | |||
| void clickedUntsSave(ActionEvent event) { | |||
| void clickedUntsSave() { | |||
| if (state.get() == State.CREATE) { | |||
| Untersuchung untersuchung = new Untersuchung(); | |||
| untersuchung.setFall(mainController.getFallController().getFall()); | |||
| @@ -225,6 +261,9 @@ public class UntersuchungenController { | |||
| } | |||
| /** | |||
| * Copy the currently selected Untersuchung object into the fields on the right. | |||
| */ | |||
| private void copyUntersuchungDataIntoFields(){ | |||
| Untersuchung untersuchung = untsList.getSelectionModel().getSelectedItem(); | |||
| if(untersuchung==null){ | |||
| @@ -242,12 +281,19 @@ public class UntersuchungenController { | |||
| untsChangeTime.setText(untersuchung.getBearbeitetDatumZeit().toString()); | |||
| } | |||
| /** | |||
| * Copies the values from the TextFields and ComboBoxes into the given Untersuchung object. | |||
| * @param untersuchung The object the data will be copied into. | |||
| */ | |||
| private void copyFieldDataIntoUntersuchung(Untersuchung untersuchung){ | |||
| untersuchung.setOpscode(untsOpsCode.getValue()); | |||
| untersuchung.setDurchfuehrenderArzt(untsArzt.getValue()); | |||
| untersuchung.setUntersuchungsdatum(dtTmUntersuchungszeitpunkt.getDateTime()); | |||
| } | |||
| /** | |||
| * Clears the TextFields. | |||
| */ | |||
| private void clearFields(){ | |||
| untsCreateTime.setText(""); | |||
| untsCreator.setText(""); | |||
| @@ -18,20 +18,66 @@ import javafx.scene.text.FontWeight; | |||
| import javafx.util.Duration; | |||
| /** | |||
| * A simple Button with a letter icon that manages an IntegerProperty. Blinks if the integer is greater than zero. | |||
| * | |||
| * Created by Johannes on 21/11/2015. | |||
| * | |||
| * @author Johannes | |||
| */ | |||
| public class MessageIcon extends Button { | |||
| private ImageView imageView; | |||
| /** | |||
| * The letter image. | |||
| */ | |||
| private final ImageView imageView = new ImageView(new Image("message.png"));; | |||
| private Label messageCountLabel; | |||
| /** | |||
| * The message number label in the center of the button. | |||
| */ | |||
| private final Label messageCountLabel = new Label(); | |||
| /** | |||
| * The messge count. | |||
| */ | |||
| private final SimpleIntegerProperty messageCount = new SimpleIntegerProperty(this, "messageCount", 0); | |||
| FadeTransition transition; | |||
| /** | |||
| * The blinking animation. | |||
| */ | |||
| private FadeTransition transition; | |||
| /** | |||
| * Public parameterless constructor, required for the FXMLLoader. | |||
| */ | |||
| public MessageIcon(){ | |||
| initImage(); | |||
| initLabel(); | |||
| initTransition(); | |||
| //Disable if no messages. | |||
| this.disableProperty().bind(messageCount.lessThanOrEqualTo(0)); | |||
| //Show image and label in the button. | |||
| this.setGraphic(new StackPane(imageView, messageCountLabel)); | |||
| } | |||
| /** | |||
| * Inits the label with the message count. | |||
| */ | |||
| private void initLabel(){ | |||
| messageCountLabel.textProperty().bind(messageCount.asString()); | |||
| messageCountLabel.setFont(Font.font("", FontWeight.BOLD, 20)); | |||
| StackPane.setAlignment(messageCountLabel, Pos.CENTER); | |||
| messageCountLabel.textFillProperty().bind(Bindings.createObjectBinding( | |||
| () -> (messageCount.get() > 0? Color.DARKRED: Color.BLACK), messageCount)); | |||
| } | |||
| public MessageIcon(){ | |||
| imageView = new ImageView(new Image("message.png")); | |||
| /** | |||
| * Inits the letter image with shadow etc. | |||
| */ | |||
| private void initImage(){ | |||
| imageView.setFitHeight(30); | |||
| imageView.setFitWidth(30); | |||
| /* imageView.opacityProperty().bind(Bindings.createDoubleBinding( | |||
| @@ -44,25 +90,11 @@ public class MessageIcon extends Button { | |||
| ()->messageCount.get() > 0 ? ds1:null, messageCount | |||
| )); | |||
| messageCountLabel = new Label(); | |||
| messageCountLabel.textProperty().bind(messageCount.asString()); | |||
| messageCountLabel.setFont(Font.font("", FontWeight.BOLD, 20)); | |||
| StackPane.setAlignment(messageCountLabel, Pos.CENTER); | |||
| messageCountLabel.textFillProperty().bind(Bindings.createObjectBinding( | |||
| () -> (messageCount.get() > 0? Color.DARKRED: Color.BLACK), messageCount)); | |||
| this.disableProperty().bind(messageCount.lessThanOrEqualTo(0)); | |||
| StackPane graphic = new StackPane(imageView, messageCountLabel); | |||
| this.setGraphic(graphic); | |||
| initTransition(); | |||
| } | |||
| /** | |||
| * Set up blinking effect. | |||
| */ | |||
| private void initTransition(){ | |||
| transition = new FadeTransition(Duration.millis(500), imageView); | |||
| transition.setFromValue(0.2); | |||
| @@ -79,14 +111,26 @@ public class MessageIcon extends Button { | |||
| }); | |||
| } | |||
| /** | |||
| * Getter for the {@link #messageCountProperty()} | |||
| * @return The messageCountProperty's value. | |||
| */ | |||
| public int getMessageCount() { | |||
| return messageCount.get(); | |||
| } | |||
| /** | |||
| * The count of messages that this view will indicate. | |||
| * @return A property for the count of messages. | |||
| */ | |||
| public SimpleIntegerProperty messageCountProperty() { | |||
| return messageCount; | |||
| } | |||
| /** | |||
| * Setter for the {@link #messageCountProperty()} | |||
| * @param messageCount The value to be set in the message count property. | |||
| */ | |||
| public void setMessageCount(int messageCount) { | |||
| this.messageCount.set(messageCount); | |||
| } | |||
| @@ -4,9 +4,10 @@ package de.uniluebeck.mi.projmi6.view; | |||
| import javafx.scene.control.TextField; | |||
| /** | |||
| * based on http://blog.axxg.de/javafx-textfield-beschraenken/ | |||
| * Based on <a href="http://blog.axxg.de/javafx-textfield-beschraenken/" >http://blog.axxg.de/javafx-textfield-beschraenken/</a> | |||
| * | |||
| * TextField that only allows two numbers. | |||
| * TextField that only allows two digit characters. | |||
| * Using the {@link javafx.scene.control.TextFormatter} would be better. | |||
| * | |||
| * Created by Johannes on 14/11/2015. | |||
| */ | |||