package regexgolf2.controllers; import java.io.IOException; import java.util.Optional; import javafx.beans.property.ObjectProperty; import javafx.beans.property.ReadOnlyBooleanProperty; import javafx.beans.property.ReadOnlyBooleanWrapper; import javafx.beans.property.ReadOnlyObjectProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.scene.Node; import javafx.stage.Window; import javax.swing.JOptionPane; import regexgolf2.model.ObjectChangedListener; import regexgolf2.model.ObservableObject; import regexgolf2.model.SolvableChallenge; import regexgolf2.model.challengegenerator.Generator; import regexgolf2.services.challengegenerator.ChallengeGeneratorService; import regexgolf2.services.persistence.PersistenceException; import regexgolf2.services.persistence.PersistenceService; import regexgolf2.services.persistence.changetracking.PersistenceState; import regexgolf2.services.services.Services; import regexgolf2.ui.challengegenerator.ChallengeGeneratorUI; import regexgolf2.ui.challengegenerator.GeneratorItem; import com.google.java.contract.Requires; public class ChallengeGeneratorController implements ChallengeContainer { private static final ReadOnlyBooleanProperty _EDITABLE = new ReadOnlyBooleanWrapper(false); private ChallengeGeneratorUI _ui; private final GeneratorConfigUICreator _configUICreator = new GeneratorConfigUICreator(); private final ObjectProperty<SolvableChallenge> _challenge = new SimpleObjectProperty<SolvableChallenge>(); private final ChallengeGeneratorService _generatorService; private final PersistenceService _persistenceService; private final ObjectChangedListener _challengeListener; private final ObjectChangedListener _persStateListener; private boolean _isSaved = false; @Requires("services != null") public ChallengeGeneratorController(Services services, Window parent) throws IOException { _generatorService = services.getGeneratorService(); _persistenceService = services.getPersistenceService(); WordRepositoryController wrc = new WordRepositoryController(services.getPersistenceService()); _ui = new ChallengeGeneratorUI(parent); _ui.setWordRepositoryPanel(wrc.getUINode()); _ui.getGenerateButton().setOnAction(e -> generateButtonClicked()); // ChoiceBox _ui.getGeneratorChoiceBox().getSelectionModel().selectedItemProperty() .addListener((o, oV, nV) -> choiceBoxSelectionChanged(nV)); initChoiceBoxItems(); // ChallengeNameTextField _ui.getChallengeNameTextField().textProperty() .addListener((o, oV, nV) -> challengeNameTextFieldChanged(nV)); // Save Button _ui.getSaveButton().setOnAction(e -> saveButtonClicked()); // ChallengeProperty Listener _challenge.addListener((o, oV, nV) -> challengePropertyChanged(oV, nV)); // Listener for the Challenge itself _challengeListener = e -> challengeChanged(); // Listener for the PersistenceState of the Challenge _persStateListener = e -> persistenceStateChanged(); } private void initChoiceBoxItems() { for (Generator g : _generatorService.getGenerators()) { GeneratorItem item = new GeneratorItem(g); _ui.getGeneratorChoiceBox().getItems().add(item); if (_generatorService.getSelectedGenerator() == g) _ui.getGeneratorChoiceBox().getSelectionModel().select(item); } } private void generateButtonClicked() { SolvableChallenge c = _generatorService.generateChallenge(); setChallenge(c); } private void challengePropertyChanged(SolvableChallenge oldChallenge, SolvableChallenge newChallenge) { if (oldChallenge != null) { oldChallenge.removeObjectChangedListener(_challengeListener); Optional.ofNullable(getPersistenceState(oldChallenge)) .ifPresent(ps -> ps.removeObjectChangedListener(_persStateListener)); _isSaved = false; persistenceStateChanged(); } if (newChallenge != null) { newChallenge.addObjectChangedListener(_challengeListener); _ui.getChallengeNameTextField().setText(getChallenge().getChallenge().getName()); } } private void challengeChanged() { _ui.getChallengeNameTextField().setText(getChallenge().getChallenge().getName()); } private void persistenceStateChanged() { boolean isChanged; if (_isSaved) // If it is saved to the DB, get ChangeState from Repository isChanged = _persistenceService.getPersistenceInformation().isChanged(getChallenge()); else isChanged = true; _ui.getSaveButton().setDisable(!isChanged); } private void saveButtonClicked() { if (getChallenge() == null) return; try { _persistenceService.save(getChallenge()); if (!_isSaved) { _isSaved = true; getPersistenceState(getChallenge()).addObjectChangedListener(_persStateListener); persistenceStateChanged(); } } catch (PersistenceException e) { JOptionPane.showMessageDialog(null, "Error with Database"); } } private void challengeNameTextFieldChanged(String newText) { if (getChallenge() == null) return; getChallenge().getChallenge().setName(newText); } private void choiceBoxSelectionChanged(GeneratorItem selectedItem) { Generator gen = selectedItem.getGenerator(); _generatorService.setSelectedGenerator(gen); _ui.setGeneratorConfigPaneContent(_configUICreator.getUIFor(gen.getConfig())); } /** * Sets the selected Challenge */ private void setChallenge(SolvableChallenge challenge) { _challenge.set(challenge); } public SolvableChallenge getChallenge() { return _challenge.get(); } @Override public ReadOnlyObjectProperty<SolvableChallenge> challengeProperty() { return _challenge; } @Override public ReadOnlyBooleanProperty editableProperty() { return _EDITABLE; } private PersistenceState getPersistenceState(ObservableObject object) { return _persistenceService.getPersistenceInformation().getPersistenceState(object); } public Node getUINode() { return _ui.getUINode(); } }