| Author | Karl Tauber <email> |
|---|---|
| Date | 2015-07-23 16:07:37 GMT+0200 |
| Commit | d29b160453c95ed61e53b2f4eec9e2c111189df2 |
| Parent | a0a29a7 |
| import java.nio.file.Files; | ||
| import java.nio.file.Path; | ||
| +import javafx.beans.binding.Bindings; | ||
| import javafx.beans.property.ObjectProperty; | ||
| +import javafx.beans.property.ReadOnlyBooleanProperty; | ||
| +import javafx.beans.property.ReadOnlyBooleanWrapper; | ||
| import javafx.beans.property.SimpleObjectProperty; | ||
| import javafx.scene.control.Alert; | ||
| FileEditor(Path path) { | ||
| this.path.set(path); | ||
| - this.path.addListener((observable, oldPath, newPath) -> updateTab()); | ||
| // avoid that this is GCed | ||
| tab.setUserData(this); | ||
| + this.path.addListener((observable, oldPath, newPath) -> updateTab()); | ||
| + this.modified.addListener((observable, oldPath, newPath) -> updateTab()); | ||
| updateTab(); | ||
| } | ||
| - // path property | ||
| + // 'path' property | ||
| private final ObjectProperty<Path> path = new SimpleObjectProperty<>(); | ||
| Path getPath() { return path.get(); } | ||
| void setPath(Path path) { this.path.set(path); } | ||
| ObjectProperty<Path> pathProperty() { return path; } | ||
| + | ||
| + // 'modified' property | ||
| + private final ReadOnlyBooleanWrapper modified = new ReadOnlyBooleanWrapper(); | ||
| + boolean isModified() { return modified.get(); } | ||
| + ReadOnlyBooleanProperty modifiedProperty() { return modified; } | ||
| private void updateTab() { | ||
| Path path = this.path.get(); | ||
| - tab.setText((path != null) ? path.getFileName().toString() : "Untitled"); | ||
| + String text = (path != null) ? path.getFileName().toString() : "Untitled"; | ||
| + if (isModified()) | ||
| + text = "*".concat(text); | ||
| + tab.setText(text); | ||
| tab.setTooltip((path != null) ? new Tooltip(path.toString()) : null); | ||
| } | ||
| // bind preview to editor | ||
| markdownPreviewPane.markdownASTProperty().bind(markdownEditorPane.markdownASTProperty()); | ||
| + | ||
| + // bind the editor undo manager to the 'modified' property | ||
| + modified.bind(Bindings.not(markdownEditorPane.getUndoManager().atMarkedPositionProperty())); | ||
| SplitPane splitPane = new SplitPane(markdownEditorPane.getNode(), markdownPreviewPane.getNode()); | ||
| String markdown = new String(Files.readAllBytes(path)); | ||
| markdownEditorPane.setMarkdown(markdown); | ||
| + markdownEditorPane.getUndoManager().mark(); | ||
| } catch (IOException ex) { | ||
| Alert alert = new Alert(AlertType.ERROR); | ||
| try { | ||
| Files.write(path.get(), markdown.getBytes()); | ||
| + markdownEditorPane.getUndoManager().mark(); | ||
| return true; | ||
| } catch (IOException ex) { | ||
| import java.util.List; | ||
| import javafx.application.Platform; | ||
| +import javafx.beans.binding.Bindings; | ||
| +import javafx.beans.property.BooleanProperty; | ||
| +import javafx.beans.property.ObjectProperty; | ||
| +import javafx.beans.property.SimpleBooleanProperty; | ||
| +import javafx.beans.property.SimpleObjectProperty; | ||
| import javafx.event.ActionEvent; | ||
| import javafx.event.Event; | ||
| private final BorderPane borderPane = new BorderPane(); | ||
| private final TabPane tabPane = new TabPane(); | ||
| + | ||
| + private final ObjectProperty<FileEditor> activeFileEditor = new SimpleObjectProperty<>(); | ||
| + private final BooleanProperty activeModified = new SimpleBooleanProperty(); | ||
| public MainWindow() { | ||
| borderPane.setPrefSize(800, 800); | ||
| borderPane.setTop(new VBox(createMenuBar(), createToolBar())); | ||
| borderPane.setCenter(tabPane); | ||
| tabPane.setTabClosingPolicy(TabClosingPolicy.ALL_TABS); | ||
| + tabPane.getSelectionModel().selectedItemProperty().addListener((observable, oldTab, newTab) -> { | ||
| + if (newTab != null) { | ||
| + activeFileEditor.set((FileEditor) newTab.getUserData()); | ||
| + activeModified.bind(activeFileEditor.get().modifiedProperty()); | ||
| + } else { | ||
| + activeFileEditor.set(null); | ||
| + activeModified.unbind(); | ||
| + activeModified.set(false); | ||
| + } | ||
| + }); | ||
| fileNew(); | ||
| MenuItem fileCloseMenuItem = createMenuItem("Close", "Shortcut+W", null, e -> fileClose()); | ||
| MenuItem fileExitMenuItem = createMenuItem("Exit", null, null, e -> fileExit()); | ||
| + | ||
| + fileSaveMenuItem.disableProperty().bind(Bindings.not(activeModified)); | ||
| + fileCloseMenuItem.disableProperty().bind(activeFileEditor.isNull()); | ||
| Menu fileMenu = new Menu("File", null, | ||
| Button fileOpenButton = createToolBarButton(FOLDER_OPEN_ALT, "Open", "Shortcut+O", e -> fileOpen()); | ||
| Button fileSaveButton = createToolBarButton(FLOPPY_ALT, "Save", "Shortcut+S", e -> fileSave()); | ||
| + | ||
| + fileSaveButton.disableProperty().bind(Bindings.not(activeModified)); | ||
| return new ToolBar( | ||
| import javafx.scene.Node; | ||
| import org.fxmisc.richtext.StyleClassedTextArea; | ||
| +import org.fxmisc.undo.UndoManager; | ||
| import org.pegdown.Extensions; | ||
| import org.pegdown.PegDownProcessor; | ||
| } | ||
| - // markdown property | ||
| + public UndoManager getUndoManager() { | ||
| + return textArea.getUndoManager(); | ||
| + } | ||
| + | ||
| + // 'markdown' property | ||
| public String getMarkdown() { return textArea.getText(); } | ||
| public void setMarkdown(String markdown) { textArea.replaceText(markdown); } | ||
| public ObservableValue<String> markdownProperty() { return textArea.textProperty(); } | ||
| - // markdownAST property | ||
| + // 'markdownAST' property | ||
| public RootNode getMarkdownAST() { return markdownAST.get(); } | ||
| public ReadOnlyObjectProperty<RootNode> markdownASTProperty() { return markdownAST.getReadOnlyProperty(); } | ||
| Delta | 50 lines added, 5 lines removed, 45-line increase |
|---|