Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/keenwrite.git

Address compiler warnings

AuthorDaveJarvis <email>
Date2020-05-30 11:30:31 GMT-0700
Commit90dc59fb36febb09d6524c50e74fb35c2ece6218
Parentc2500f4
Delta378 lines added, 415 lines removed, 37-line decrease
src/main/java/com/scrivenvar/FileEditorTab.java
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
-import javafx.event.Event;
-import javafx.scene.Node;
-import javafx.scene.Scene;
-import javafx.scene.control.Tab;
-import javafx.scene.control.Tooltip;
-import javafx.scene.input.InputEvent;
-import javafx.scene.text.Text;
-import javafx.stage.Window;
-import org.fxmisc.richtext.StyleClassedTextArea;
-import org.fxmisc.richtext.model.TwoDimensional.Position;
-import org.fxmisc.undo.UndoManager;
-import org.fxmisc.wellbehaved.event.EventPattern;
-import org.fxmisc.wellbehaved.event.InputMap;
-import org.mozilla.universalchardet.UniversalDetector;
-
-import java.io.IOException;
-import java.nio.charset.Charset;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.function.Consumer;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-import static java.util.Locale.ENGLISH;
-import static org.fxmisc.richtext.model.TwoDimensional.Bias.Forward;
-
-/**
- * Editor for a single file.
- *
- * @author Karl Tauber and White Magic Software, Ltd.
- */
-public final class FileEditorTab extends Tab {
-
- /**
- *
- */
- private final Notifier alertService = Services.load( Notifier.class );
- private EditorPane editorPane;
-
- /**
- * Character encoding used by the file (or default encoding if none found).
- */
- private Charset mEncoding = UTF_8;
-
- private final ReadOnlyBooleanWrapper mModified = new ReadOnlyBooleanWrapper();
- private final BooleanProperty canUndo = new SimpleBooleanProperty();
- private final BooleanProperty canRedo = new SimpleBooleanProperty();
-
- private Path mPath;
-
- public FileEditorTab( final Path path ) {
- setPath( path );
-
- mModified.addListener( ( observable, oldPath, newPath ) -> updateTab() );
-
- setOnSelectionChanged( e -> {
- if( isSelected() ) {
- Platform.runLater( this::activated );
- }
- } );
- }
-
- private void updateTab() {
- setText( getTabTitle() );
- setGraphic( getModifiedMark() );
- setTooltip( getTabTooltip() );
- }
-
- /**
- * Returns the base filename (without the directory names).
- *
- * @return The untitled text if the path hasn't been set.
- */
- private String getTabTitle() {
- final Path filePath = getPath();
-
- return (filePath == null)
- ? Messages.get( "FileEditor.untitled" )
- : filePath.getFileName().toString();
- }
-
- /**
- * Returns the full filename represented by the path.
- *
- * @return The untitled text if the path hasn't been set.
- */
- private Tooltip getTabTooltip() {
- final Path filePath = getPath();
- return new Tooltip( filePath == null ? "" : filePath.toString() );
- }
-
- /**
- * Returns a marker to indicate whether the file has been modified.
- *
- * @return "*" when the file has changed; otherwise null.
- */
- private Text getModifiedMark() {
- return isModified() ? new Text( "*" ) : null;
- }
-
- /**
- * Called when the user switches tab.
- */
- private void activated() {
- // Tab is closed or no longer active.
- if( getTabPane() == null || !isSelected() ) {
- return;
- }
-
- // Switch to the tab without loading if the contents are already in memory.
- if( getContent() != null ) {
- getEditorPane().requestFocus();
- return;
- }
-
- // Load the text and update the preview before the undo manager.
- load();
-
- // Track undo requests -- can only be called *after* load.
- initUndoManager();
- initLayout();
- initFocus();
- }
-
- private void initLayout() {
- setContent( getScrollPane() );
- }
-
- private Node getScrollPane() {
- return getEditorPane().getScrollPane();
- }
-
- private void initFocus() {
- getEditorPane().requestFocus();
- }
-
- private void initUndoManager() {
- final UndoManager undoManager = getUndoManager();
- undoManager.forgetHistory();
-
- // Bind the editor undo manager to the properties.
- mModified.bind( Bindings.not( undoManager.atMarkedPositionProperty() ) );
- canUndo.bind( undoManager.undoAvailableProperty() );
- canRedo.bind( undoManager.redoAvailableProperty() );
- }
-
- /**
- * Searches from the caret position forward for the given string.
- *
- * @param needle The text string to match.
- */
- public void searchNext( final String needle ) {
- final String haystack = getEditorText();
- int index = haystack.indexOf( needle, getCaretPosition() );
-
- // Wrap around.
- if( index == -1 ) {
- index = haystack.indexOf( needle, 0 );
- }
-
- if( index >= 0 ) {
- setCaretPosition( index );
- getEditor().selectRange( index, index + needle.length() );
- }
- }
-
- /**
- * Returns the index into the text where the caret blinks happily away.
- *
- * @return A number from 0 to the editor's document text length.
- */
- public int getCaretPosition() {
- return getEditor().getCaretPosition();
- }
-
- /**
- * Moves the caret to a given offset.
- *
- * @param offset The new caret offset.
- */
- private void setCaretPosition( final int offset ) {
- getEditor().moveTo( offset );
- getEditor().requestFollowCaret();
- }
-
- /**
- * Returns the caret's current row and column position.
- *
- * @return The caret's offset into the document.
- */
- public Position getCaretOffset() {
- return getEditor().offsetToPosition( getCaretPosition(), Forward );
- }
-
- /**
- * Allows observers to synchronize caret position changes.
- *
- * @return An observable caret property value.
- */
- public final ObservableValue<Integer> caretPositionProperty() {
- return getEditor().caretPositionProperty();
- }
-
- /**
- * Returns the text area associated with this tab.
- *
- * @return A text editor.
- */
- private StyleClassedTextArea getEditor() {
- return getEditorPane().getEditor();
- }
-
- /**
- * Returns true if the given path exactly matches this tab's path.
- *
- * @param check The path to compare against.
- * @return true The paths are the same.
- */
- public boolean isPath( final Path check ) {
- final Path filePath = getPath();
-
- return filePath != null && filePath.equals( check );
- }
-
- /**
- * Reads the entire file contents from the path associated with this tab.
- */
- private void load() {
- final Path filePath = getPath();
-
- if( filePath != null ) {
- try {
- getEditorPane().setText( asString( Files.readAllBytes( filePath ) ) );
- getEditorPane().scrollToTop();
- } catch( final Exception ex ) {
- getNotifyService().notify( ex );
- }
- }
- }
-
- /**
- * Saves the entire file contents from the path associated with this tab.
- *
- * @return true The file has been saved.
- */
- public boolean save() {
- try {
- final EditorPane editor = getEditorPane();
- Files.write( getPath(), asBytes( editor.getText() ) );
- editor.getUndoManager().mark();
- return true;
- } catch( final IOException ex ) {
- return alert(
- "FileEditor.saveFailed.title", "FileEditor.saveFailed.message", ex
- );
- }
- }
-
- /**
- * Creates an alert dialog and waits for it to close.
- *
- * @param titleKey Resource bundle key for the alert dialog title.
- * @param messageKey Resource bundle key for the alert dialog message.
- * @param e The unexpected happening.
- * @return false
- */
- @SuppressWarnings("SameParameterValue")
- private boolean alert(
- final String titleKey, final String messageKey, final Exception e ) {
- final Notifier service = getNotifyService();
- final Path filePath = getPath();
-
- final Notification message = service.createNotification(
- Messages.get( titleKey ),
- Messages.get( messageKey ),
- filePath == null ? "" : filePath,
- e.getMessage()
- );
-
- try {
- service.createError( getWindow(), message ).showAndWait();
- } catch( final Exception ex ) {
- getNotifyService().notify( ex );
- }
-
- return false;
- }
-
- private Window getWindow() {
- final Scene scene = getEditorPane().getScene();
-
- if( scene == null ) {
- throw new UnsupportedOperationException( "No scene window available" );
- }
-
- return scene.getWindow();
- }
-
- /**
- * Returns a best guess at the file encoding. If the encoding could not be
- * detected, this will return the default charset for the JVM.
- *
- * @param bytes The bytes to perform character encoding detection.
- * @return The character encoding.
- */
- private Charset detectEncoding( final byte[] bytes ) {
- final UniversalDetector detector = new UniversalDetector( null );
- detector.handleData( bytes, 0, bytes.length );
- detector.dataEnd();
-
- final String charset = detector.getDetectedCharset();
- final Charset charEncoding = charset == null
- ? Charset.defaultCharset()
- : Charset.forName( charset.toUpperCase( ENGLISH ) );
-
- detector.reset();
-
- return charEncoding;
- }
-
- /**
- * Converts the given string to an array of bytes using the encoding that was
- * originally detected (if any) and associated with this file.
- *
- * @param text The text to convert into the original file encoding.
- * @return A series of bytes ready for writing to a file.
- */
- private byte[] asBytes( final String text ) {
- return text.getBytes( getEncoding() );
- }
-
- /**
- * Converts the given bytes into a Java String. This will call setEncoding
- * with the encoding detected by the CharsetDetector.
- *
- * @param text The text of unknown character encoding.
- * @return The text, in its auto-detected encoding, as a String.
- */
- private String asString( final byte[] text ) {
- setEncoding( detectEncoding( text ) );
- return new String( text, getEncoding() );
- }
-
- /**
- * Returns the path to the file being edited in this tab.
- *
- * @return A non-null instance.
- */
- public Path getPath() {
- return mPath;
- }
-
- /**
- * Sets the path to a file for editing and then updates the tab with the
- * file contents.
- *
- * @param path A non-null instance.
- */
- public void setPath( final Path path ) {
- assert path != null;
-
- mPath = path;
-
- updateTab();
- }
-
- public boolean isModified() {
- return mModified.get();
- }
-
- ReadOnlyBooleanProperty modifiedProperty() {
- return mModified.getReadOnlyProperty();
- }
-
- BooleanProperty canUndoProperty() {
- return this.canUndo;
- }
-
- BooleanProperty canRedoProperty() {
- return this.canRedo;
- }
-
- private UndoManager getUndoManager() {
- return getEditorPane().getUndoManager();
- }
-
- /**
- * Forwards the request to the editor pane.
- *
- * @param <T> The type of event listener to add.
- * @param <U> The type of consumer to add.
- * @param event The event that should trigger updates to the listener.
- * @param consumer The listener to receive update events.
- */
- public <T extends Event, U extends T> void addEventListener(
- final EventPattern<? super T, ? extends U> event,
- final Consumer<? super U> consumer ) {
- getEditorPane().addKeyboardListener( event, consumer );
- }
-
- /**
- * Forwards to the editor pane's listeners for keyboard events.
- *
- * @param map The new input map to replace the existing keyboard listener.
- */
- public void addEventListener( final InputMap<InputEvent> map ) {
- getEditorPane().addEventListener( map );
- }
-
- /**
- * Forwards to the editor pane's listeners for keyboard events.
- *
- * @param map The existing input map to remove from the keyboard listeners.
- */
- public void removeEventListener( final InputMap<InputEvent> map ) {
- getEditorPane().removeEventListener( map );
+import javafx.scene.Node;
+import javafx.scene.Scene;
+import javafx.scene.control.Tab;
+import javafx.scene.control.Tooltip;
+import javafx.scene.text.Text;
+import javafx.stage.Window;
+import org.fxmisc.richtext.StyleClassedTextArea;
+import org.fxmisc.richtext.model.TwoDimensional.Position;
+import org.fxmisc.undo.UndoManager;
+import org.mozilla.universalchardet.UniversalDetector;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static java.util.Locale.ENGLISH;
+import static org.fxmisc.richtext.model.TwoDimensional.Bias.Forward;
+
+/**
+ * Editor for a single file.
+ *
+ * @author Karl Tauber and White Magic Software, Ltd.
+ */
+public final class FileEditorTab extends Tab {
+
+ /**
+ *
+ */
+ private final Notifier alertService = Services.load( Notifier.class );
+ private EditorPane editorPane;
+
+ /**
+ * Character encoding used by the file (or default encoding if none found).
+ */
+ private Charset mEncoding = UTF_8;
+
+ private final ReadOnlyBooleanWrapper mModified = new ReadOnlyBooleanWrapper();
+ private final BooleanProperty canUndo = new SimpleBooleanProperty();
+ private final BooleanProperty canRedo = new SimpleBooleanProperty();
+
+ private Path mPath;
+
+ public FileEditorTab( final Path path ) {
+ setPath( path );
+
+ mModified.addListener( ( observable, oldPath, newPath ) -> updateTab() );
+
+ setOnSelectionChanged( e -> {
+ if( isSelected() ) {
+ Platform.runLater( this::activated );
+ }
+ } );
+ }
+
+ private void updateTab() {
+ setText( getTabTitle() );
+ setGraphic( getModifiedMark() );
+ setTooltip( getTabTooltip() );
+ }
+
+ /**
+ * Returns the base filename (without the directory names).
+ *
+ * @return The untitled text if the path hasn't been set.
+ */
+ private String getTabTitle() {
+ final Path filePath = getPath();
+
+ return (filePath == null)
+ ? Messages.get( "FileEditor.untitled" )
+ : filePath.getFileName().toString();
+ }
+
+ /**
+ * Returns the full filename represented by the path.
+ *
+ * @return The untitled text if the path hasn't been set.
+ */
+ private Tooltip getTabTooltip() {
+ final Path filePath = getPath();
+ return new Tooltip( filePath == null ? "" : filePath.toString() );
+ }
+
+ /**
+ * Returns a marker to indicate whether the file has been modified.
+ *
+ * @return "*" when the file has changed; otherwise null.
+ */
+ private Text getModifiedMark() {
+ return isModified() ? new Text( "*" ) : null;
+ }
+
+ /**
+ * Called when the user switches tab.
+ */
+ private void activated() {
+ // Tab is closed or no longer active.
+ if( getTabPane() == null || !isSelected() ) {
+ return;
+ }
+
+ // Switch to the tab without loading if the contents are already in memory.
+ if( getContent() != null ) {
+ getEditorPane().requestFocus();
+ return;
+ }
+
+ // Load the text and update the preview before the undo manager.
+ load();
+
+ // Track undo requests -- can only be called *after* load.
+ initUndoManager();
+ initLayout();
+ initFocus();
+ }
+
+ private void initLayout() {
+ setContent( getScrollPane() );
+ }
+
+ private Node getScrollPane() {
+ return getEditorPane().getScrollPane();
+ }
+
+ private void initFocus() {
+ getEditorPane().requestFocus();
+ }
+
+ private void initUndoManager() {
+ final UndoManager<?> undoManager = getUndoManager();
+ undoManager.forgetHistory();
+
+ // Bind the editor undo manager to the properties.
+ mModified.bind( Bindings.not( undoManager.atMarkedPositionProperty() ) );
+ canUndo.bind( undoManager.undoAvailableProperty() );
+ canRedo.bind( undoManager.redoAvailableProperty() );
+ }
+
+ /**
+ * Searches from the caret position forward for the given string.
+ *
+ * @param needle The text string to match.
+ */
+ public void searchNext( final String needle ) {
+ final String haystack = getEditorText();
+ int index = haystack.indexOf( needle, getCaretPosition() );
+
+ // Wrap around.
+ if( index == -1 ) {
+ index = haystack.indexOf( needle );
+ }
+
+ if( index >= 0 ) {
+ setCaretPosition( index );
+ getEditor().selectRange( index, index + needle.length() );
+ }
+ }
+
+ /**
+ * Returns the index into the text where the caret blinks happily away.
+ *
+ * @return A number from 0 to the editor's document text length.
+ */
+ public int getCaretPosition() {
+ return getEditor().getCaretPosition();
+ }
+
+ /**
+ * Moves the caret to a given offset.
+ *
+ * @param offset The new caret offset.
+ */
+ private void setCaretPosition( final int offset ) {
+ getEditor().moveTo( offset );
+ getEditor().requestFollowCaret();
+ }
+
+ /**
+ * Returns the caret's current row and column position.
+ *
+ * @return The caret's offset into the document.
+ */
+ public Position getCaretOffset() {
+ return getEditor().offsetToPosition( getCaretPosition(), Forward );
+ }
+
+ /**
+ * Allows observers to synchronize caret position changes.
+ *
+ * @return An observable caret property value.
+ */
+ public final ObservableValue<Integer> caretPositionProperty() {
+ return getEditor().caretPositionProperty();
+ }
+
+ /**
+ * Returns the text area associated with this tab.
+ *
+ * @return A text editor.
+ */
+ private StyleClassedTextArea getEditor() {
+ return getEditorPane().getEditor();
+ }
+
+ /**
+ * Returns true if the given path exactly matches this tab's path.
+ *
+ * @param check The path to compare against.
+ * @return true The paths are the same.
+ */
+ public boolean isPath( final Path check ) {
+ final Path filePath = getPath();
+
+ return filePath != null && filePath.equals( check );
+ }
+
+ /**
+ * Reads the entire file contents from the path associated with this tab.
+ */
+ private void load() {
+ final Path filePath = getPath();
+
+ if( filePath != null ) {
+ try {
+ getEditorPane().setText( asString( Files.readAllBytes( filePath ) ) );
+ getEditorPane().scrollToTop();
+ } catch( final Exception ex ) {
+ getNotifyService().notify( ex );
+ }
+ }
+ }
+
+ /**
+ * Saves the entire file contents from the path associated with this tab.
+ *
+ * @return true The file has been saved.
+ */
+ public boolean save() {
+ try {
+ final EditorPane editor = getEditorPane();
+ Files.write( getPath(), asBytes( editor.getText() ) );
+ editor.getUndoManager().mark();
+ return true;
+ } catch( final IOException ex ) {
+ return alert(
+ "FileEditor.saveFailed.title", "FileEditor.saveFailed.message", ex
+ );
+ }
+ }
+
+ /**
+ * Creates an alert dialog and waits for it to close.
+ *
+ * @param titleKey Resource bundle key for the alert dialog title.
+ * @param messageKey Resource bundle key for the alert dialog message.
+ * @param e The unexpected happening.
+ * @return false
+ */
+ @SuppressWarnings("SameParameterValue")
+ private boolean alert(
+ final String titleKey, final String messageKey, final Exception e ) {
+ final Notifier service = getNotifyService();
+ final Path filePath = getPath();
+
+ final Notification message = service.createNotification(
+ Messages.get( titleKey ),
+ Messages.get( messageKey ),
+ filePath == null ? "" : filePath,
+ e.getMessage()
+ );
+
+ try {
+ service.createError( getWindow(), message ).showAndWait();
+ } catch( final Exception ex ) {
+ getNotifyService().notify( ex );
+ }
+
+ return false;
+ }
+
+ private Window getWindow() {
+ final Scene scene = getEditorPane().getScene();
+
+ if( scene == null ) {
+ throw new UnsupportedOperationException( "No scene window available" );
+ }
+
+ return scene.getWindow();
+ }
+
+ /**
+ * Returns a best guess at the file encoding. If the encoding could not be
+ * detected, this will return the default charset for the JVM.
+ *
+ * @param bytes The bytes to perform character encoding detection.
+ * @return The character encoding.
+ */
+ private Charset detectEncoding( final byte[] bytes ) {
+ final UniversalDetector detector = new UniversalDetector( null );
+ detector.handleData( bytes, 0, bytes.length );
+ detector.dataEnd();
+
+ final String charset = detector.getDetectedCharset();
+ final Charset charEncoding = charset == null
+ ? Charset.defaultCharset()
+ : Charset.forName( charset.toUpperCase( ENGLISH ) );
+
+ detector.reset();
+
+ return charEncoding;
+ }
+
+ /**
+ * Converts the given string to an array of bytes using the encoding that was
+ * originally detected (if any) and associated with this file.
+ *
+ * @param text The text to convert into the original file encoding.
+ * @return A series of bytes ready for writing to a file.
+ */
+ private byte[] asBytes( final String text ) {
+ return text.getBytes( getEncoding() );
+ }
+
+ /**
+ * Converts the given bytes into a Java String. This will call setEncoding
+ * with the encoding detected by the CharsetDetector.
+ *
+ * @param text The text of unknown character encoding.
+ * @return The text, in its auto-detected encoding, as a String.
+ */
+ private String asString( final byte[] text ) {
+ setEncoding( detectEncoding( text ) );
+ return new String( text, getEncoding() );
+ }
+
+ /**
+ * Returns the path to the file being edited in this tab.
+ *
+ * @return A non-null instance.
+ */
+ public Path getPath() {
+ return mPath;
+ }
+
+ /**
+ * Sets the path to a file for editing and then updates the tab with the
+ * file contents.
+ *
+ * @param path A non-null instance.
+ */
+ public void setPath( final Path path ) {
+ assert path != null;
+
+ mPath = path;
+
+ updateTab();
+ }
+
+ public boolean isModified() {
+ return mModified.get();
+ }
+
+ ReadOnlyBooleanProperty modifiedProperty() {
+ return mModified.getReadOnlyProperty();
+ }
+
+ BooleanProperty canUndoProperty() {
+ return this.canUndo;
+ }
+
+ BooleanProperty canRedoProperty() {
+ return this.canRedo;
+ }
+
+ private UndoManager<?> getUndoManager() {
+ return getEditorPane().getUndoManager();
}