| Author | Karl Tauber <email> |
|---|---|
| Date | 2015-07-24 22:33:38 GMT+0200 |
| Commit | 3f065fcb40fa3508b5ffa0021e9f29d7ab2464b6 |
| Parent | 128d6f1 |
| Delta | 71 lines added, 17 lines removed, 54-line increase |
| import javafx.beans.property.ReadOnlyObjectProperty; | ||
| import javafx.beans.property.ReadOnlyObjectWrapper; | ||
| +import javafx.beans.value.ChangeListener; | ||
| +import javafx.collections.ListChangeListener; | ||
| import javafx.collections.ObservableList; | ||
| import javafx.event.Event; | ||
| private final ReadOnlyObjectWrapper<FileEditor> activeFileEditor = new ReadOnlyObjectWrapper<>(); | ||
| private final ReadOnlyBooleanWrapper activeFileEditorModified = new ReadOnlyBooleanWrapper(); | ||
| + private final ReadOnlyBooleanWrapper anyFileEditorModified = new ReadOnlyBooleanWrapper(); | ||
| FileEditorTabPane(MainWindow mainWindow) { | ||
| this.mainWindow = mainWindow; | ||
| tabPane = new TabPane(); | ||
| tabPane.setFocusTraversable(false); | ||
| tabPane.setTabClosingPolicy(TabClosingPolicy.ALL_TABS); | ||
| + | ||
| + // update activeFileEditor and activeFileEditorModified properties | ||
| tabPane.getSelectionModel().selectedItemProperty().addListener((observable, oldTab, newTab) -> { | ||
| if (newTab != null) { | ||
| activeFileEditor.set((FileEditor) newTab.getUserData()); | ||
| activeFileEditorModified.bind(activeFileEditor.get().modifiedProperty()); | ||
| } else { | ||
| activeFileEditor.set(null); | ||
| activeFileEditorModified.unbind(); | ||
| activeFileEditorModified.set(false); | ||
| + } | ||
| + }); | ||
| + | ||
| + // update anyFileEditorModified property | ||
| + ChangeListener<Boolean> modifiedListener = (observable, oldValue, newValue) -> { | ||
| + boolean modified = false; | ||
| + for (Tab tab : tabPane.getTabs()) { | ||
| + if (((FileEditor)tab.getUserData()).isModified()) { | ||
| + modified = true; | ||
| + break; | ||
| + } | ||
| + } | ||
| + anyFileEditorModified.set(modified); | ||
| + }; | ||
| + tabPane.getTabs().addListener((ListChangeListener<Tab>) c -> { | ||
| + while (c.next()) { | ||
| + if (c.wasAdded()) { | ||
| + for (Tab tab : c.getAddedSubList()) | ||
| + ((FileEditor)tab.getUserData()).modifiedProperty().addListener(modifiedListener); | ||
| + } else if (c.wasRemoved()) { | ||
| + for (Tab tab : c.getRemoved()) | ||
| + ((FileEditor)tab.getUserData()).modifiedProperty().removeListener(modifiedListener); | ||
| + } | ||
| } | ||
| + | ||
| + // changes in the tabs may also change anyFileEditorModified property | ||
| + // (e.g. closed modified file) | ||
| + modifiedListener.changed(null, null, null); | ||
| }); | ||
| ReadOnlyBooleanProperty activeFileEditorModifiedProperty() { | ||
| return activeFileEditorModified.getReadOnlyProperty(); | ||
| + } | ||
| + | ||
| + ReadOnlyBooleanProperty anyFileEditorModifiedProperty() { | ||
| + return anyFileEditorModified.getReadOnlyProperty(); | ||
| } | ||
| boolean saveEditor(FileEditor fileEditor) { | ||
| - if (fileEditor == null) | ||
| - return false; | ||
| + if (fileEditor == null || !fileEditor.isModified()) | ||
| + return true; | ||
| if (fileEditor.getPath() == null) { | ||
| + tabPane.getSelectionModel().select(fileEditor.getTab()); | ||
| + | ||
| FileChooser fileChooser = createFileChooser("Save Markdown File"); | ||
| File file = fileChooser.showSaveDialog(mainWindow.getScene().getWindow()); | ||
| if (file == null) | ||
| return false; | ||
| fileEditor.setPath(file.toPath()); | ||
| } | ||
| return fileEditor.save(); | ||
| + } | ||
| + | ||
| + boolean saveAllEditors() { | ||
| + FileEditor[] allEditors = getAllEditors(); | ||
| + | ||
| + boolean success = true; | ||
| + for (FileEditor fileEditor : allEditors) { | ||
| + if (!saveEditor(fileEditor)) | ||
| + success = false; | ||
| + } | ||
| + | ||
| + return success; | ||
| } | ||
| import javafx.beans.binding.Bindings; | ||
| -import javafx.beans.property.ReadOnlyBooleanProperty; | ||
| -import javafx.beans.property.ReadOnlyObjectProperty; | ||
| import javafx.event.ActionEvent; | ||
| import javafx.event.Event; | ||
| Scene getScene() { | ||
| return scene; | ||
| - } | ||
| - | ||
| - private ReadOnlyObjectProperty<FileEditor> activeFileEditor() { | ||
| - return fileEditorTabPane.activeFileEditorProperty(); | ||
| - } | ||
| - | ||
| - private ReadOnlyBooleanProperty activeFileEditorModified() { | ||
| - return fileEditorTabPane.activeFileEditorModifiedProperty(); | ||
| } | ||
| private MenuBar createMenuBar() { | ||
| // File menu | ||
| MenuItem fileNewMenuItem = createMenuItem("New", "Shortcut+N", FILE_ALT, e -> fileNew()); | ||
| MenuItem fileOpenMenuItem = createMenuItem("Open...", "Shortcut+O", FOLDER_OPEN_ALT, e -> fileOpen()); | ||
| MenuItem fileCloseMenuItem = createMenuItem("Close", "Shortcut+W", null, e -> fileClose()); | ||
| + MenuItem fileCloseAllMenuItem = createMenuItem("Close All", null, null, e -> fileCloseAll()); | ||
| MenuItem fileSaveMenuItem = createMenuItem("Save", "Shortcut+S", FLOPPY_ALT, e -> fileSave()); | ||
| + MenuItem fileSaveAllMenuItem = createMenuItem("Save All", "Shortcut+Shift+S", null, e -> fileSaveAll()); | ||
| MenuItem fileExitMenuItem = createMenuItem("Exit", null, null, e -> fileExit()); | ||
| - fileCloseMenuItem.disableProperty().bind(activeFileEditor().isNull()); | ||
| - fileSaveMenuItem.disableProperty().bind(Bindings.not(activeFileEditorModified())); | ||
| + fileCloseMenuItem.disableProperty().bind(fileEditorTabPane.activeFileEditorProperty().isNull()); | ||
| + fileCloseAllMenuItem.disableProperty().bind(fileEditorTabPane.activeFileEditorProperty().isNull()); | ||
| + fileSaveMenuItem.disableProperty().bind(Bindings.not(fileEditorTabPane.activeFileEditorModifiedProperty())); | ||
| + fileSaveAllMenuItem.disableProperty().bind(Bindings.not(fileEditorTabPane.anyFileEditorModifiedProperty())); | ||
| Menu fileMenu = new Menu("File", null, | ||
| fileNewMenuItem, | ||
| fileOpenMenuItem, | ||
| new SeparatorMenuItem(), | ||
| fileCloseMenuItem, | ||
| + fileCloseAllMenuItem, | ||
| new SeparatorMenuItem(), | ||
| fileSaveMenuItem, | ||
| + fileSaveAllMenuItem, | ||
| new SeparatorMenuItem(), | ||
| fileExitMenuItem); | ||
| Button fileSaveButton = createToolBarButton(FLOPPY_ALT, "Save", "Shortcut+S", e -> fileSave()); | ||
| - fileSaveButton.disableProperty().bind(Bindings.not(activeFileEditorModified())); | ||
| + fileSaveButton.disableProperty().bind(Bindings.not(fileEditorTabPane.activeFileEditorModifiedProperty())); | ||
| return new ToolBar( | ||
| private void fileClose() { | ||
| - fileEditorTabPane.closeEditor(activeFileEditor().get()); | ||
| + fileEditorTabPane.closeEditor(fileEditorTabPane.activeFileEditorProperty().get()); | ||
| + } | ||
| + | ||
| + private void fileCloseAll() { | ||
| + fileEditorTabPane.closeAllEditors(); | ||
| } | ||
| private void fileSave() { | ||
| - fileEditorTabPane.saveEditor(activeFileEditor().get()); | ||
| + fileEditorTabPane.saveEditor(fileEditorTabPane.activeFileEditorProperty().get()); | ||
| + } | ||
| + | ||
| + private void fileSaveAll() { | ||
| + fileEditorTabPane.saveAllEditors(); | ||
| } | ||