package nl.itopia.corendon.mvc; import javafx.collections.ObservableList; import javafx.fxml.FXMLLoader; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.layout.Pane; import nl.itopia.corendon.utils.IO; import nl.itopia.corendon.utils.Log; import nl.itopia.corendon.view.DialogBackground; import java.io.IOException; import java.net.URL; /** * © Biodiscus.net 2014, Robin */ public abstract class Controller { private MVC mvc; protected View view; private ObjectDelete controllerDeleteHandler; public Controller() {} /** * Register a FXML View. The FXML view will be added to a new View. * @param path String */ public void registerFXML(String path) { registerFXML(path, new View()); } /** * Register a FXML View. The FXML view will be added to the View. * @param path String * @param view View */ public void registerFXML(String path, View view) { this.view = view; // Get the URL inside the JAR URL url = IO.get(path); try { // Load the FXML file FXMLLoader loader = new FXMLLoader(url); loader.setController(this); view.fxmlPane = loader.load(); // Add it to the view view.getChildren().add(view.fxmlPane); } catch (IOException e) { Log.display("IOEXCEPTION", e.getMessage()); e.printStackTrace(); } } /** * Set the current MVC engine, this way we can change the controller in a controller * @param mvc MVC */ public final void setMVCEngine(MVC mvc) { this.mvc = mvc; } /** * Change the current controller to the new one * @param controller Controller */ public final void changeController(Controller controller) { mvc.setController(controller); } /** * Adds a new controller to the scene. If no root is given, the Controller will be added to the current controller * (The one that called this function) * @param controller Controller */ public final void addController(Controller controller) { addController(controller, getView()); } /** * Adds a new controller to the scene. If no root is given, the Controller will be added to the current controller * (The one that called this function) * @param controller Controller */ public final void addController(Controller controller, Pane root) { // If the root is null, change the controller instead if(root == null) { changeController(controller); } else { // Add a shadow on the view Scene scene = root.getScene(); DialogBackground dialogBackground = new DialogBackground(scene); // Set the dialog background so the method removeController can remove the view controller.getView().dialogBackground = dialogBackground; ObservableList<Node> nodeList = root.getChildren(); nodeList.add(dialogBackground); nodeList.add(controller.getView()); } } /** * Removes the given controller. If a controller delete handler is set, fire it. * Override destroyReturn() to specify what object will be return upon deletion. * @param controller */ public final void removeController(Controller controller) { Pane parent = (Pane)controller.getView().getParent(); // TODO: When the root in addController is null, it should do something else. if(parent != null) { View view = controller.getView(); if(view.dialogBackground != null) { Pane dialogParent = (Pane) view.dialogBackground.getParent(); dialogParent.getChildren().remove(view.dialogBackground); } parent.getChildren().remove(view); } if(controllerDeleteHandler != null) { controllerDeleteHandler.action(destroyReturn()); } } /** * When creating the class, the programs allows for a ObjectDelete handler. * This will send an object to the set handler, with a object from the method destroyReturn() * @param handler */ public void setControllerDeleteHandler(ObjectDelete handler) { this.controllerDeleteHandler = handler; } // Override this function to give the destroy handler an object to return /** * Override the destroyReturn function to specify what object to send with the handler when destroyed. * @return */ protected Object destroyReturn() { return null; } /** * Get the view associated with the controller * @return */ public View getView() { return view; } }