From 44bd6c0a65e6954eb4822f3e26c5abb11dc63958 Mon Sep 17 00:00:00 2001 From: Victor Date: Wed, 6 Sep 2017 11:03:33 +0300 Subject: [PATCH] Add an ability to open files, move IO methods to separate package --- .../main/java/com/annimon/hotarufx/Main.java | 1 + .../annimon/hotarufx/io/DocumentListener.java | 6 ++ .../annimon/hotarufx/io/DocumentManager.java | 14 ++++ .../com/annimon/hotarufx/io/FileManager.java | 68 +++++++++++++++++++ .../com/annimon/hotarufx/io/IOStream.java | 20 ++++++ .../ui/controller/EditorController.java | 36 +++++++--- app/src/main/resources/fxml/Editor.fxml | 1 + 7 files changed, 135 insertions(+), 11 deletions(-) create mode 100644 app/src/main/java/com/annimon/hotarufx/io/DocumentListener.java create mode 100644 app/src/main/java/com/annimon/hotarufx/io/DocumentManager.java create mode 100644 app/src/main/java/com/annimon/hotarufx/io/FileManager.java create mode 100644 app/src/main/java/com/annimon/hotarufx/io/IOStream.java diff --git a/app/src/main/java/com/annimon/hotarufx/Main.java b/app/src/main/java/com/annimon/hotarufx/Main.java index 29bec95..131ed6b 100644 --- a/app/src/main/java/com/annimon/hotarufx/Main.java +++ b/app/src/main/java/com/annimon/hotarufx/Main.java @@ -25,6 +25,7 @@ public class Main extends Application { getClass().getResource("/styles/color-picker-box.css").toExternalForm() ); controller = loader.getController(); + controller.setPrimaryStage(primaryStage); primaryStage.setScene(scene); } catch (IOException e) { // TODO: notice me!! diff --git a/app/src/main/java/com/annimon/hotarufx/io/DocumentListener.java b/app/src/main/java/com/annimon/hotarufx/io/DocumentListener.java new file mode 100644 index 0000000..2d249c6 --- /dev/null +++ b/app/src/main/java/com/annimon/hotarufx/io/DocumentListener.java @@ -0,0 +1,6 @@ +package com.annimon.hotarufx.io; + +public interface DocumentListener { + + void logError(String message); +} diff --git a/app/src/main/java/com/annimon/hotarufx/io/DocumentManager.java b/app/src/main/java/com/annimon/hotarufx/io/DocumentManager.java new file mode 100644 index 0000000..5011725 --- /dev/null +++ b/app/src/main/java/com/annimon/hotarufx/io/DocumentManager.java @@ -0,0 +1,14 @@ +package com.annimon.hotarufx.io; + +import java.util.function.Consumer; +import javafx.stage.Stage; + +public interface DocumentManager { + + void newDocument(); + + boolean open(Stage stage, Consumer contentConsumer); + + + void addDocumentListener(DocumentListener listener); +} diff --git a/app/src/main/java/com/annimon/hotarufx/io/FileManager.java b/app/src/main/java/com/annimon/hotarufx/io/FileManager.java new file mode 100644 index 0000000..da4819b --- /dev/null +++ b/app/src/main/java/com/annimon/hotarufx/io/FileManager.java @@ -0,0 +1,68 @@ +package com.annimon.hotarufx.io; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.function.Consumer; +import javafx.stage.FileChooser; +import javafx.stage.Stage; +import lombok.val; + +public class FileManager implements DocumentManager { + + private static final String FILE_OPEN_TITLE = "Select file to open"; + private final FileChooser fileChooser; + private File currentFile; + private DocumentListener listener; + + public FileManager() { + fileChooser = new FileChooser(); + fileChooser.getExtensionFilters().setAll( + new FileChooser.ExtensionFilter("Supported Files", "*.hfx") + ); + } + + @Override + public void newDocument() { + currentFile = null; + } + + @Override + public boolean open(Stage stage, Consumer contentConsumer) { + fileChooser.setTitle(FILE_OPEN_TITLE); + if (currentFile != null) { + fileChooser.setInitialDirectory(currentFile.getParentFile()); + } + currentFile = fileChooser.showOpenDialog(stage); + if (currentFile == null) { + return false; + } + if (!currentFile.exists() || !currentFile.isFile()) { + return false; + } + + val content = readFile(currentFile); + if (content.isEmpty()) { + return false; + } + contentConsumer.accept(content); + return true; + } + + @Override + public void addDocumentListener(DocumentListener listener) { + this.listener = listener; + } + + private String readFile(File file) { + try (InputStream is = new FileInputStream(file)) { + return IOStream.readContent(is); + } catch (IOException ioe) { + if (listener != null) { + listener.logError("Unable to open file " + file.getName()); + } + return ""; + } + } +} diff --git a/app/src/main/java/com/annimon/hotarufx/io/IOStream.java b/app/src/main/java/com/annimon/hotarufx/io/IOStream.java new file mode 100644 index 0000000..c66c597 --- /dev/null +++ b/app/src/main/java/com/annimon/hotarufx/io/IOStream.java @@ -0,0 +1,20 @@ +package com.annimon.hotarufx.io; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import lombok.val; + +public class IOStream { + + public static String readContent(InputStream is) throws IOException { + val baos = new ByteArrayOutputStream(); + val bufferSize = 4096; + val buffer = new byte[bufferSize]; + int read; + while ((read = is.read(buffer, 0, bufferSize)) != -1) { + baos.write(buffer, 0, read); + } + return baos.toString("UTF-8"); + } +} diff --git a/app/src/main/java/com/annimon/hotarufx/ui/controller/EditorController.java b/app/src/main/java/com/annimon/hotarufx/ui/controller/EditorController.java index f4254e3..bf951ae 100644 --- a/app/src/main/java/com/annimon/hotarufx/ui/controller/EditorController.java +++ b/app/src/main/java/com/annimon/hotarufx/ui/controller/EditorController.java @@ -4,12 +4,15 @@ import com.annimon.hotarufx.Main; import com.annimon.hotarufx.bundles.BundleLoader; import com.annimon.hotarufx.bundles.CompositionBundle; import com.annimon.hotarufx.bundles.NodesBundle; +import com.annimon.hotarufx.io.DocumentListener; +import com.annimon.hotarufx.io.IOStream; import com.annimon.hotarufx.lexer.HotaruLexer; import com.annimon.hotarufx.lib.Context; import com.annimon.hotarufx.parser.HotaruParser; import com.annimon.hotarufx.parser.visitors.InterpreterVisitor; +import com.annimon.hotarufx.io.DocumentManager; +import com.annimon.hotarufx.io.FileManager; import com.annimon.hotarufx.ui.SyntaxHighlighter; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; @@ -27,7 +30,7 @@ import lombok.val; import org.fxmisc.richtext.CodeArea; import org.fxmisc.richtext.LineNumberFactory; -public class EditorController implements Initializable { +public class EditorController implements Initializable, DocumentListener { @FXML private CodeArea editor; @@ -37,7 +40,15 @@ public class EditorController implements Initializable { @FXML private TitledPane logPane; + private Stage primaryStage; private SyntaxHighlighter syntaxHighlighter; + private DocumentManager documentManager; + + @FXML + private void handleMenuOpen(ActionEvent event) { + documentManager.open(primaryStage, + s -> editor.replaceText(0, 0, s)); + } @FXML private void handleMenuExit(ActionEvent event) { @@ -81,27 +92,30 @@ public class EditorController implements Initializable { editor.setParagraphGraphicFactory(LineNumberFactory.get(editor)); syntaxHighlighter = new SyntaxHighlighter(editor, Executors.newSingleThreadExecutor()); syntaxHighlighter.init(); + documentManager = new FileManager(); editor.replaceText(0, 0, readProgram("/main.hfx")); } + public void setPrimaryStage(Stage primaryStage) { + this.primaryStage = primaryStage; + } + public void stop() { syntaxHighlighter.release(); } - private static String readProgram(String path) { + @Override + public void logError(String message) { + log.insertText(0, message + System.lineSeparator()); + } + + private String readProgram(String path) { val fallbackProgram = "composition(640, 480, 25)"; try (InputStream is = Main.class.getResourceAsStream(path)) { if (is == null) { return fallbackProgram; } - val baos = new ByteArrayOutputStream(); - val bufferSize = 4096; - val buffer = new byte[bufferSize]; - int read; - while ((read = is.read(buffer, 0, bufferSize)) != -1) { - baos.write(buffer, 0, read); - } - return baos.toString("UTF-8"); + return IOStream.readContent(is); } catch (IOException ioe) { return fallbackProgram; } diff --git a/app/src/main/resources/fxml/Editor.fxml b/app/src/main/resources/fxml/Editor.fxml index 4eaa723..1d091f6 100644 --- a/app/src/main/resources/fxml/Editor.fxml +++ b/app/src/main/resources/fxml/Editor.fxml @@ -21,6 +21,7 @@ +