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:
parent
2eab11b8af
commit
44bd6c0a65
@ -25,6 +25,7 @@ public class Main extends Application {
|
|||||||
getClass().getResource("/styles/color-picker-box.css").toExternalForm()
|
getClass().getResource("/styles/color-picker-box.css").toExternalForm()
|
||||||
);
|
);
|
||||||
controller = loader.getController();
|
controller = loader.getController();
|
||||||
|
controller.setPrimaryStage(primaryStage);
|
||||||
primaryStage.setScene(scene);
|
primaryStage.setScene(scene);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// TODO: notice me!!
|
// TODO: notice me!!
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
package com.annimon.hotarufx.io;
|
||||||
|
|
||||||
|
public interface DocumentListener {
|
||||||
|
|
||||||
|
void logError(String message);
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
68
app/src/main/java/com/annimon/hotarufx/io/FileManager.java
Normal file
68
app/src/main/java/com/annimon/hotarufx/io/FileManager.java
Normal 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 "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
20
app/src/main/java/com/annimon/hotarufx/io/IOStream.java
Normal file
20
app/src/main/java/com/annimon/hotarufx/io/IOStream.java
Normal 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");
|
||||||
|
}
|
||||||
|
}
|
@ -4,12 +4,15 @@ import com.annimon.hotarufx.Main;
|
|||||||
import com.annimon.hotarufx.bundles.BundleLoader;
|
import com.annimon.hotarufx.bundles.BundleLoader;
|
||||||
import com.annimon.hotarufx.bundles.CompositionBundle;
|
import com.annimon.hotarufx.bundles.CompositionBundle;
|
||||||
import com.annimon.hotarufx.bundles.NodesBundle;
|
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.lexer.HotaruLexer;
|
||||||
import com.annimon.hotarufx.lib.Context;
|
import com.annimon.hotarufx.lib.Context;
|
||||||
import com.annimon.hotarufx.parser.HotaruParser;
|
import com.annimon.hotarufx.parser.HotaruParser;
|
||||||
import com.annimon.hotarufx.parser.visitors.InterpreterVisitor;
|
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 com.annimon.hotarufx.ui.SyntaxHighlighter;
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
@ -27,7 +30,7 @@ import lombok.val;
|
|||||||
import org.fxmisc.richtext.CodeArea;
|
import org.fxmisc.richtext.CodeArea;
|
||||||
import org.fxmisc.richtext.LineNumberFactory;
|
import org.fxmisc.richtext.LineNumberFactory;
|
||||||
|
|
||||||
public class EditorController implements Initializable {
|
public class EditorController implements Initializable, DocumentListener {
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private CodeArea editor;
|
private CodeArea editor;
|
||||||
@ -37,7 +40,15 @@ public class EditorController implements Initializable {
|
|||||||
@FXML
|
@FXML
|
||||||
private TitledPane logPane;
|
private TitledPane logPane;
|
||||||
|
|
||||||
|
private Stage primaryStage;
|
||||||
private SyntaxHighlighter syntaxHighlighter;
|
private SyntaxHighlighter syntaxHighlighter;
|
||||||
|
private DocumentManager documentManager;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private void handleMenuOpen(ActionEvent event) {
|
||||||
|
documentManager.open(primaryStage,
|
||||||
|
s -> editor.replaceText(0, 0, s));
|
||||||
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private void handleMenuExit(ActionEvent event) {
|
private void handleMenuExit(ActionEvent event) {
|
||||||
@ -81,27 +92,30 @@ public class EditorController implements Initializable {
|
|||||||
editor.setParagraphGraphicFactory(LineNumberFactory.get(editor));
|
editor.setParagraphGraphicFactory(LineNumberFactory.get(editor));
|
||||||
syntaxHighlighter = new SyntaxHighlighter(editor, Executors.newSingleThreadExecutor());
|
syntaxHighlighter = new SyntaxHighlighter(editor, Executors.newSingleThreadExecutor());
|
||||||
syntaxHighlighter.init();
|
syntaxHighlighter.init();
|
||||||
|
documentManager = new FileManager();
|
||||||
editor.replaceText(0, 0, readProgram("/main.hfx"));
|
editor.replaceText(0, 0, readProgram("/main.hfx"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPrimaryStage(Stage primaryStage) {
|
||||||
|
this.primaryStage = primaryStage;
|
||||||
|
}
|
||||||
|
|
||||||
public void stop() {
|
public void stop() {
|
||||||
syntaxHighlighter.release();
|
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)";
|
val fallbackProgram = "composition(640, 480, 25)";
|
||||||
try (InputStream is = Main.class.getResourceAsStream(path)) {
|
try (InputStream is = Main.class.getResourceAsStream(path)) {
|
||||||
if (is == null) {
|
if (is == null) {
|
||||||
return fallbackProgram;
|
return fallbackProgram;
|
||||||
}
|
}
|
||||||
val baos = new ByteArrayOutputStream();
|
return IOStream.readContent(is);
|
||||||
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");
|
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
return fallbackProgram;
|
return fallbackProgram;
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
<VBox BorderPane.alignment="CENTER">
|
<VBox BorderPane.alignment="CENTER">
|
||||||
<MenuBar>
|
<MenuBar>
|
||||||
<Menu mnemonicParsing="false" text="File">
|
<Menu mnemonicParsing="false" text="File">
|
||||||
|
<MenuItem onAction="#handleMenuOpen" text="Open"/>
|
||||||
<MenuItem onAction="#handleMenuExit" text="Exit"/>
|
<MenuItem onAction="#handleMenuExit" text="Exit"/>
|
||||||
</Menu>
|
</Menu>
|
||||||
<Menu mnemonicParsing="false" text="Composition">
|
<Menu mnemonicParsing="false" text="Composition">
|
||||||
|
Loading…
Reference in New Issue
Block a user