/* * Michael Goldenberg, Jinghui Yu, and Ben Borchard modified this file on 10/27/13 * with the following changes: * * 1.) Removed one try catch and allOkay variable and replaced it with a try catch for a validation exception */ package cpusim.gui.editmodules.arrayregisters; import cpusim.Mediator; import cpusim.gui.editmodules.RegisterArrayTableController; import cpusim.gui.editmodules.RegistersTableController; import cpusim.gui.help.HelpController; import cpusim.model.module.Register; import cpusim.model.module.RegisterArray; import cpusim.util.Dialogs; import cpusim.util.Validate; import cpusim.util.ValidationException; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.Node; import javafx.scene.control.*; import javafx.scene.input.InputEvent; import javafx.scene.input.MouseEvent; import javafx.scene.layout.Pane; import javafx.stage.Stage; import java.net.URL; import java.util.*; import java.util.stream.Collectors; public class EditArrayRegistersController implements Initializable { @FXML ComboBox<String> arrayCombo; @FXML Pane tablePane; @FXML Button okButton; @FXML Button cancelButton; @FXML Button helpButton; private Mediator mediator; private RegistersTableController registerController; private ObservableList<RegisterArray> registerArrays; private TableView activeTable; private ChangeTable tableMap; private String selection; public EditArrayRegistersController(Mediator mediator, RegistersTableController registerTableController, RegisterArrayTableController controller, String selected) { this.mediator = mediator; this.registerController = registerTableController; this.registerArrays = controller.getItems(); activeTable = null; selection = selected; } public EditArrayRegistersController(Mediator mediator, RegistersTableController registerTableController, RegisterArrayTableController controller) { this.mediator = mediator; this.registerController = registerTableController; this.registerArrays = controller.getItems(); activeTable = null; selection = registerArrays.get(0).getName(); } /** * initializes the dialog window after its root element has been processed. * contains a listener to the combo box, so that the content of the table will * change according to the selected type of microinstruction. * * @param url the location used to resolve relative paths for the root * object, or null if the location is not known. * @param rb the resources used to localize the root object, or null if the root * object was not localized. */ @Override public void initialize(URL url, ResourceBundle rb) { arrayCombo.getItems().addAll(registerArrays.stream().map( RegisterArray::getName).collect(Collectors.toList())); arrayCombo.getSelectionModel().select(selection); tableMap = new ChangeTable(registerArrays); tableMap.setParents(tablePane); tablePane.getChildren().clear(); tablePane.getChildren().add(tableMap.getMap().get(selection)); activeTable = tableMap.getMap().get(selection); activeTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); // resizes the width and height of the content panes tablePane.widthProperty().addListener((observableValue, oldValue, newValue) -> activeTable.setPrefWidth((Double) newValue) ); tablePane.heightProperty().addListener((observableValue, oldValue, newValue) -> activeTable.setPrefHeight((Double) newValue) ); // listen for changes to the instruction combo box selection and update // the displayed micro instruction table accordingly. arrayCombo.getSelectionModel().selectedItemProperty().addListener( new ChangeListener<String>() { @Override public void changed(ObservableValue<? extends String> selected, String oldType, String newType) { ((RegisterArrayTableView) activeTable).setClones(activeTable .getItems()); activeTable = tableMap.getMap().get(newType); tableMap.getMap().get(oldType).getSelectionModel() .clearSelection(); tablePane.getChildren().clear(); tablePane.getChildren().add( tableMap.getMap().get(newType)); activeTable.setPrefWidth(tablePane.getWidth()); activeTable.setPrefHeight(tablePane.getHeight()); activeTable.setColumnResizePolicy(TableView .CONSTRAINED_RESIZE_POLICY); } }); // Define an event filter for the ComboBox for Mouse_released events EventHandler validityFilter = new EventHandler<InputEvent>() { public void handle(InputEvent event) { try { ObservableList<Register> list = FXCollections.observableArrayList(); list.addAll(registerController.getItems()); for (RegisterArrayTableView r : tableMap.getMap().values()) { list.addAll(r.getItems()); } Validate.allNamesAreUnique(list.toArray()); ((RegisterArrayTableView) activeTable).checkValidity(list); } catch (ValidationException ex) { Dialogs.createErrorDialog(tablePane.getScene().getWindow(), "Registers Error", ex.getMessage()).showAndWait(); event.consume(); } } }; arrayCombo.addEventFilter(MouseEvent.MOUSE_RELEASED, validityFilter); } /** * save the current changes and close the window when clicking on OK button. * * @param e a type of action when a button is clicked. */ @FXML public void onOKButtonClick(ActionEvent e) { //get the current edited clones ObservableList objList = activeTable.getItems(); try { ObservableList<Register> list = FXCollections.observableArrayList(); list.addAll(registerController.getItems()); for (RegisterArrayTableView r : tableMap.getMap().values()) { list.addAll(r.getItems()); } Validate.allNamesAreUnique(list.toArray()); getCurrentController().checkValidity(objList); //update the machine with the new values updateRegisters(); //get a handle to the stage. Stage stage = (Stage) okButton.getScene().getWindow(); //close window. stage.close(); } catch (Exception ex) { Dialogs.createErrorDialog(tablePane.getScene().getWindow(), "Registers Error", ex.getMessage()).showAndWait(); } } /** * close the window without saving the changes. * * @param e a type of action when a button is clicked. */ @FXML public void onCancelButtonClick(ActionEvent e) { //get a handle to the stage. Stage stage = (Stage) cancelButton.getScene().getWindow(); //close window. stage.close(); } /** * open a help window when clicking on the help button. * * @param e a type of action when a button is clicked. */ @FXML public void onHelpButtonClick(ActionEvent e) { String startString = "Hardware Modules"; if (mediator.getDesktopController().getHelpController() == null) { HelpController helpController = HelpController.openHelpDialog( mediator.getDesktopController(), startString); mediator.getDesktopController().setHelpController(helpController); } else { HelpController hc = mediator.getDesktopController().getHelpController(); hc.getStage().toFront(); hc.selectTreeItem(startString); } } /** * gets the table view object that is current being edited in the window. * * @return the table view object that is current being edited in the window. */ public RegisterArrayTableView getCurrentController() { return tableMap.getMap().get(arrayCombo.getValue()); } /** * Called whenever the dialog is exited via the 'ok' button * and the machine needs to be updated based on the changes * made while the dialog was open (JRL) */ protected void updateRegisters() { // and the machine needs to be updated based on the changes // made. getCurrentController().setClones(activeTable.getItems()); for (RegisterArrayTableView t : tableMap.getMap().values()) { for (RegisterArray ra : registerArrays) { if (ra.getName().equals(t.getArrayName())) { ra.registers().setAll(t.createNewModulesList(t.getClones())); } } } } /** * a class that holds the current register array class */ class ChangeTable { Map<String, RegisterArrayTableView> typesMap; /** * Constructor * * @param arrays the current register array */ public ChangeTable(ObservableList<RegisterArray> arrays) { // an hashmap that holds types as the keys and sub fxml names as values. typesMap = buildMap(arrays); } /** * build the map to store all the controllers * * @param arrays a list holds all the register array objects * @return the map that contains all the controllers */ public Map buildMap(ObservableList<RegisterArray> arrays) { Map<String, RegisterArrayTableView> map = new HashMap(); for (RegisterArray ra : arrays) { map.put(ra.getName(), new RegisterArrayTableView(ra.getName(), ra .registers())); } return map; } /** * returns the map of controllers. * * @return the map of controllers. */ public Map<String, RegisterArrayTableView> getMap() { return typesMap; } /** * sets the parents frame for each controller. * * @param tables the controller to be edited. */ public void setParents(Node tables) { for (RegisterArrayTableView moduleController : typesMap.values()) { moduleController.setParentFrame(tables); } } } }