1
0
mirror of https://github.com/aNNiMON/HotaruFX.git synced 2024-09-19 14:14:21 +03:00

Add an ability to open files, move IO methods to separate package

This commit is contained in:
Victor 2017-09-06 11:03:33 +03:00
parent 2eab11b8af
commit 44bd6c0a65
7 changed files with 135 additions and 11 deletions

View File

@ -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!!

View File

@ -0,0 +1,6 @@
package com.annimon.hotarufx.io;
public interface DocumentListener {
void logError(String message);
}

View File

@ -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<String> contentConsumer);
void addDocumentListener(DocumentListener listener);
}

View File

@ -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<String> 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 "";
}
}
}

View File

@ -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");
}
}

View File

@ -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;
}

View File

@ -21,6 +21,7 @@
<VBox BorderPane.alignment="CENTER">
<MenuBar>
<Menu mnemonicParsing="false" text="File">
<MenuItem onAction="#handleMenuOpen" text="Open"/>
<MenuItem onAction="#handleMenuExit" text="Exit"/>
</Menu>
<Menu mnemonicParsing="false" text="Composition">