From afcbfc893a6066cbdcf201734616a1be5ee85903 Mon Sep 17 00:00:00 2001 From: Dev Kev <69854056+DevKevYT@users.noreply.github.com> Date: Wed, 9 Sep 2020 11:02:00 +0200 Subject: [PATCH 1/7] Update changelog.txt --- changelog.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/changelog.txt b/changelog.txt index 12e59e6..81b5423 100644 --- a/changelog.txt +++ b/changelog.txt @@ -5,6 +5,16 @@ NOTICE: Another future plan: Command: "include " a command to include external compiled libraries "plug in style". Added in 1.8.0 with the command: import "path_to_jar"; +1.9.0: + - This big Update gives you an Editor GUI! It runs, if you run the program without arguments. However, if you specify arguments inside the + command line this will happen: -e or --execute: Loads this script into the editor. -f or --file Loads the file into the editor. + To launch the jar file without a GUI, you need to put an --nogui argument. + Example: java -jar devscript_1.9.0.jar --file "path_to_file" --nogui -> Executes the file inside the command line + java -jar devscript_1.9.0.jar --execute "println foo;" -> Opens the editor window with "println foo;" as the content. + - Easier input setting. Before 1.9.0, it is very complicated to implement a custom InputStream. This update provides an abstract + com.devscript.raw.ApplicationInput class, to make it easier to create inputs other than the System.in: process.setInput(new ApplicationInput() {...}); + - + 1.8.3: - New Command: use [STRING]; This command replaces the location of the command with code from the given string as the first argument. This command is especially useful, if you want to include code from a separate file without creating a whole new library. From 1f63013ff51c92ba45abe81a8695db107cf97a65 Mon Sep 17 00:00:00 2001 From: Dev Kev <69854056+DevKevYT@users.noreply.github.com> Date: Thu, 17 Sep 2020 07:41:37 +0200 Subject: [PATCH 2/7] Add files via upload --- .../devscript/raw/ApplicationInput.java | 53 ++++ .../devscript/raw/ApplicationListener.java | 6 + com/devkev/devscript/raw/Array.java | 134 ++++---- com/devkev/devscript/raw/Block.java | 5 +- com/devkev/devscript/raw/ConsoleMain.java | 6 +- com/devkev/devscript/raw/Process.java | 16 +- com/devkev/gui/Window.java | 296 ++++++++++++++++++ 7 files changed, 445 insertions(+), 71 deletions(-) create mode 100644 com/devkev/devscript/raw/ApplicationInput.java create mode 100644 com/devkev/devscript/raw/ApplicationListener.java create mode 100644 com/devkev/gui/Window.java diff --git a/com/devkev/devscript/raw/ApplicationInput.java b/com/devkev/devscript/raw/ApplicationInput.java new file mode 100644 index 0000000..49da43f --- /dev/null +++ b/com/devkev/devscript/raw/ApplicationInput.java @@ -0,0 +1,53 @@ +package com.devkev.devscript.raw; + +import java.io.IOException; +import java.io.InputStream; + +public abstract class ApplicationInput extends InputStream { + + private volatile boolean inputReqested = false; + + private String data = ""; + private int index = 0; + + @Override + public int read() throws IOException { + if(!inputReqested) { + inputReqested = true; + System.out.println("Awaiting input..."); + awaitInput(); + synchronized (this) { + try { + wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + index++; + if(index < data.length() && !data.isEmpty()) { + System.out.println("Fetching data... " + data.getBytes()[index-1]); + return data.getBytes()[index-1]; + } else { + data = ""; + index = 0; + return -1; + } + } + + /**This function is called, before */ + public abstract void awaitInput(); + + public synchronized boolean inputRequested() { + return inputReqested; + } + + public void flush(String data) { + if(inputReqested) { + this.data = data == null ? "" : data; + synchronized (this) { + notify(); + } + } + } +} diff --git a/com/devkev/devscript/raw/ApplicationListener.java b/com/devkev/devscript/raw/ApplicationListener.java new file mode 100644 index 0000000..9d866b1 --- /dev/null +++ b/com/devkev/devscript/raw/ApplicationListener.java @@ -0,0 +1,6 @@ +package com.devkev.devscript.raw; + +public interface ApplicationListener { + /**Exit codes are:
{@link Block#DONE}
{@link Block#ERROR}*/ + public void done(int exitCode); +} diff --git a/com/devkev/devscript/raw/Array.java b/com/devkev/devscript/raw/Array.java index f3a96be..344aaf3 100644 --- a/com/devkev/devscript/raw/Array.java +++ b/com/devkev/devscript/raw/Array.java @@ -1,67 +1,67 @@ -package com.devkev.devscript.raw; - -import java.util.ArrayList; - -import com.devkev.devscript.raw.ApplicationBuilder.Type; - -public class Array { //For dataContainers - private final ArrayList indexes = new ArrayList(2); - public DataType arrayType; - - public Array(Object... indexes) { - for(Object d : indexes) this.indexes.add(d); - updateArraytype(); - } - - public Array() { - updateArraytype(); - } - - public void push(Object container) { - indexes.add(container); - updateArraytype(); - } - - public void push(Object container, int index) { - indexes.add(index, container); - updateArraytype(); - } - - public void pop(int index) { - indexes.remove(index); - updateArraytype(); - } - - public void pop(Object container) { - indexes.remove(container); - updateArraytype(); - } - - public ArrayList getIndexes() { - return indexes; - } - - public void updateArraytype() { - Type type = Type.NULL; - for(int j = 0; j < indexes.size(); j++) { - DataType containerType = ApplicationBuilder.toDataType(indexes.get(j)); - if(j > 0) { - DataType indexType = ApplicationBuilder.toDataType(indexes.get(j-1)); - if(indexType.type != containerType.type && type != Type.ANY) { - type = Type.ANY; - break; - } - } else if(j == 0) { - type = containerType.type; - } - } - arrayType = new DataType(type, true); - } - - public String toString() { - String s = "ARRAY:{"; - for(int i = 0; i < indexes.size()-1; i++) s += indexes.get(i) + ","; - if(indexes.size() > 0) s += indexes.get(indexes.size()-1); - return s + "}"; - } -} +package com.devkev.devscript.raw; + +import java.util.ArrayList; + +import com.devkev.devscript.raw.ApplicationBuilder.Type; + +public class Array { //For dataContainers + private final ArrayList indexes = new ArrayList(2); + public DataType arrayType; + + public Array(Object... indexes) { + for(Object d : indexes) this.indexes.add(d); + updateArraytype(); + } + + public Array() { + updateArraytype(); + } + + public void push(Object container) { + indexes.add(container); + updateArraytype(); + } + + public void push(Object container, int index) { + indexes.add(index, container); + updateArraytype(); + } + + public void pop(int index) { + indexes.remove(index); + updateArraytype(); + } + + public void pop(Object container) { + indexes.remove(container); + updateArraytype(); + } + + public ArrayList getIndexes() { + return indexes; + } + + public void updateArraytype() { + Type type = Type.NULL; + for(int j = 0; j < indexes.size(); j++) { + DataType containerType = ApplicationBuilder.toDataType(indexes.get(j)); + if(j > 0) { + DataType indexType = ApplicationBuilder.toDataType(indexes.get(j-1)); + if(indexType.type != containerType.type && type != Type.ANY) { + type = Type.ANY; + break; + } + } else if(j == 0) { + type = containerType.type; + } + } + arrayType = new DataType(type, true); + } + + public String toString() { + String s = "ARRAY:{"; + for(int i = 0; i < indexes.size()-1; i++) s += indexes.get(i) + ","; + if(indexes.size() > 0) s += indexes.get(indexes.size()-1); + return s + "}"; + } +} diff --git a/com/devkev/devscript/raw/Block.java b/com/devkev/devscript/raw/Block.java index 526db23..3fa0091 100644 --- a/com/devkev/devscript/raw/Block.java +++ b/com/devkev/devscript/raw/Block.java @@ -4,6 +4,9 @@ public class Block { //So stupid... + public static final byte DONE = 0; + public static final byte ERROR = 1; + public final StringBuilder blockCode; public int executeIndex = 0; //The current char index, that is executed or compiled. 0 < ExecuteIndex < blockCode.length() String currentCommand = ""; @@ -20,7 +23,7 @@ public class Block { //So stupid... public boolean loop = false; ArrayList cached = new ArrayList(0); - + int exitCode = DONE; Block(StringBuilder blockCode, Block parent) { this.blockCode = blockCode; diff --git a/com/devkev/devscript/raw/ConsoleMain.java b/com/devkev/devscript/raw/ConsoleMain.java index b8d9cf0..03d1973 100644 --- a/com/devkev/devscript/raw/ConsoleMain.java +++ b/com/devkev/devscript/raw/ConsoleMain.java @@ -6,6 +6,8 @@ import java.io.InputStreamReader; import java.net.URLDecoder; +import com.devkev.gui.Window; + /**@author Philipp Gersch * @version 1.8.2 (stable) * Valid arguments are:
-e or --execute [some code] - Executes the String
@@ -46,6 +48,8 @@ public static void main(String[] args) throws IOException { System.exit(-1); } p.execute(new File(args[1]), true); - } + } else if(args[0].equals("--gui") || args[0].equals("-g")) { + new Window(); + } } } diff --git a/com/devkev/devscript/raw/Process.java b/com/devkev/devscript/raw/Process.java index 8801c2b..f35deb2 100644 --- a/com/devkev/devscript/raw/Process.java +++ b/com/devkev/devscript/raw/Process.java @@ -17,6 +17,7 @@ public class Process { private ArrayList libraries = new ArrayList(); private ArrayList output = new ArrayList(1); private ArrayList variables = new ArrayList(5); + private ApplicationListener listener; private static final boolean False = false; private static final boolean True = true; @@ -104,6 +105,7 @@ public Thread execute(String script, boolean newThread) { } script = script.replaceAll("\t", ""); + script = script.replaceAll("\r", ""); main = new Block(new StringBuilder(script), null); main.thread = null; @@ -165,6 +167,7 @@ private void start(Block block) { //char[] arr = block.blockCode.toCharArray(); StringBuilder command = new StringBuilder(); + block.exitCode = Block.DONE; block.alive = true; block.interrupted = false; if(!checkForInterrupt(block)) return; @@ -250,6 +253,7 @@ else if(c == Alphabet.COMMENT && inComment && !inQuote) { } block.alive = false; + if(block.equals(main) && listener != null) listener.done(main.exitCode); aliveBlocks.remove(block); } @@ -650,10 +654,9 @@ public GeneratedLibrary getLibrary(String name) { return null; } - /***/ public synchronized void kill(Block block, String errorMessage) { if(block == null) { - error("Error in JVM> " + errorMessage); + error("Java Error> " + errorMessage); return; } else { if (block.currentCommand.length() > 30) { @@ -671,6 +674,7 @@ public synchronized void kill(Block block, String errorMessage) { block.currentCommand = ""; } + block.exitCode = Block.ERROR; aliveBlocks.clear(); garbageCollection(main); System.gc(); @@ -768,6 +772,14 @@ public void breakLoop() { breakRequested = true; } + public void setApplicationListener(ApplicationListener listener) { + this.listener = listener; + } + + public ApplicationListener getApplicationListener() { + return listener; + } + public static String findMatching(String string, int start, int skip, char openChar, char closeChar, char escapeChar, boolean removeEscape) { char[] arr = string.toCharArray(); int wrap = 0; diff --git a/com/devkev/gui/Window.java b/com/devkev/gui/Window.java new file mode 100644 index 0000000..25088ba --- /dev/null +++ b/com/devkev/gui/Window.java @@ -0,0 +1,296 @@ +package com.devkev.gui; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.KeyEventDispatcher; +import java.awt.KeyboardFocusManager; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; + +import javax.swing.BorderFactory; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.JTextPane; +import javax.swing.KeyStroke; +import javax.swing.UIManager; +import javax.swing.WindowConstants; +import javax.swing.event.CaretEvent; +import javax.swing.event.CaretListener; +import javax.swing.text.AttributeSet; +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.StyleConstants; +import javax.swing.text.StyleContext; + +import com.devkev.devscript.raw.ApplicationInput; +import com.devkev.devscript.raw.ApplicationListener; +import com.devkev.devscript.raw.Output; +import com.devkev.devscript.raw.Process; + +public class Window { + + JFrame window; + int fontSize = 12; + JMenuBar bar; + JTextPane textArea; + JScrollPane pane; + Process p; + + ApplicationInput input; + volatile boolean waitForEnter = false; + volatile int inputStart = 0; + + private static Font font; + + public Window() { + try { + UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); + } catch (Exception evt) {} + font = new Font("Consolas", Font.PLAIN, 13); + + window = new JFrame("Devscript 1.9.0 Editor (pre alpha build)"); + window.setVisible(true); + window.setResizable(true); + window.setLayout(null); + window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + window.addComponentListener(new ComponentListener() { + public void componentResized(ComponentEvent e) { + if(textArea == null) return; + pane.setSize(window.getRootPane().getWidth() - 10, window.getRootPane().getHeight()-bar.getHeight() - 10); + pane.updateUI(); + } + public void componentShown(ComponentEvent e) {} + public void componentMoved(ComponentEvent e) {} + public void componentHidden(ComponentEvent e) {} + }); + window.setMinimumSize(new Dimension(180, 180)); + + p = new Process(true); + p.addOutput(new Output() { + public void warning(String message) { + console.append("[WARN]" + message + "\n"); + } + public void log(String message, boolean newline) { + console.append(message + (newline ? "\n" : "")); + } + public void error(String message) { + console.append(message + "\n"); + } + }); + input = new ApplicationInput() { + @Override + public void awaitInput() { + waitForEnter = true; + console.setEnabled(true); + inputStart = console.getText().length(); + console.setCaretPosition(inputStart); + console.setCaretColor(Color.blue); + } + }; + p.setInput(input); + p.setApplicationListener(new ApplicationListener() { + public void done(int exitCode) { + runWindow.setTitle("Done (Exit Code " + exitCode + ")"); + window.setEnabled(true); + console.setEnabled(false); + } + }); + + KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher() { + @Override + public boolean dispatchKeyEvent(KeyEvent e) { + if(e.getKeyCode() == KeyEvent.VK_ENTER && input.inputRequested() && waitForEnter) { + input.flush(console.getText().substring(inputStart, console.getCaretPosition()) + "\n"); + waitForEnter = false; + console.setCaretColor(Color.black); + } + return false; + } + }); + + bar = new JMenuBar(); + + JMenu m = new JMenu("File"); + + JMenuItem newFile = new JMenuItem("New"); + newFile.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + textArea.setText(""); + } + }); + m.add(newFile); + + JMenuItem loadFile = new JMenuItem("Load File"); + loadFile.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + window.setEnabled(false); + JFileChooser chooser = new JFileChooser(); + int res = chooser.showOpenDialog(new JFrame()); + if(res == JFileChooser.APPROVE_OPTION) { + try { + textArea.setText(""); + BufferedReader reader = new BufferedReader(new FileReader(chooser.getSelectedFile())); + String line = reader.readLine(); + while(line != null) { + appendToPane(textArea, "\n" + line, Color.black); + line = reader.readLine(); + } + reader.close(); + window.setEnabled(true); + } catch (Exception e1) { + e1.printStackTrace(); + window.setEnabled(true); + } + } else { + window.setEnabled(true); + } + } + }); + m.add(loadFile); + JMenuItem saveFile = new JMenuItem("Save File"); + m.add(saveFile); + bar.add(m); + + JMenu m2 = new JMenu("Edit"); + bar.add(m2); + + JMenu m3 = new JMenu("Run"); + JMenuItem run = new JMenuItem(getFormattedBarText("Run in shell")); + run.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0)); + run.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if(p.isRunning()) return; + console.setText(""); + runWindow.toFront(); + runWindow.setTitle("Running..."); + runWindow.setVisible(true); + window.setEnabled(false); + p.execute(textArea.getText(), true); + System.out.println("Done"); + } + }); + m3.add(run); + bar.add(m3); + + window.setJMenuBar(bar); + + textArea = new JTextPane(); + textArea.setFont(font); + pane = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + pane.setBounds(5, 5, window.getRootPane().getWidth() - 10, window.getRootPane().getHeight()-bar.getHeight() - 10); + pane.setBorder(BorderFactory.createLineBorder(Color.BLACK)); + window.add(pane); + + initRunWindow(); + window.pack(); + window.setSize(500, 500); + } + + JFrame runWindow; + JTextArea console; + JScrollPane consolePane; + + public void initRunWindow() { + runWindow = new JFrame(); + runWindow.setVisible(false); + runWindow.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); + runWindow.addWindowListener(new WindowListener() { + public void windowClosed(WindowEvent arg0) {} + public void windowOpened(WindowEvent arg0) {} + public void windowIconified(WindowEvent arg0) {} + public void windowDeiconified(WindowEvent arg0) {} + public void windowDeactivated(WindowEvent arg0) {} + public void windowClosing(WindowEvent arg0) { + if(p.isRunning()) { + System.out.println("Closing running instance"); + p.kill(p.getMain(), "Interrupted by program"); + } + window.setEnabled(true); + inputStart = 0; + input.flush(null); + console.setText(""); + } + public void windowActivated(WindowEvent arg0) {} + }); + runWindow.addComponentListener(new ComponentListener() { + @Override + public void componentResized(ComponentEvent e) { + console.setSize(window.getRootPane().getWidth() - 10, window.getRootPane().getHeight()-bar.getHeight() - 10); + console.updateUI(); + } + public void componentShown(ComponentEvent e) {} + public void componentMoved(ComponentEvent e) {} + public void componentHidden(ComponentEvent e) {} + }); + + console = new JTextArea(); + console.setFont(font); + console.addCaretListener(new CaretListener() { + @Override + public void caretUpdate(CaretEvent e) { + System.out.println("Updating caret..."); + System.out.println(console.getCaretPosition() + " " + inputStart); + if(input.inputRequested() && console.getCaretPosition() < inputStart) { + console.setCaretPosition(inputStart); + } + } + }); + console.addKeyListener(new KeyListener() { + @Override + public void keyTyped(KeyEvent e) {} + public void keyReleased(KeyEvent e) {} + public void keyPressed(KeyEvent e) { + if(!input.inputRequested()) return; + if(console.getCaretPosition() == inputStart && e.getKeyCode() == KeyEvent.VK_BACK_SPACE) { + e.consume(); + } + } + }); + + console.setEnabled(false); + console.setDisabledTextColor(Color.DARK_GRAY); + consolePane = new JScrollPane(console, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + consolePane.setBounds(5, 5, runWindow.getRootPane().getWidth()-10, runWindow.getRootPane().getHeight()-10); + consolePane.setBorder(BorderFactory.createLineBorder(Color.BLACK)); + runWindow.add(consolePane); + + runWindow.pack(); + runWindow.setBounds((int) (Toolkit.getDefaultToolkit().getScreenSize().width *.5f-250), (int) (Toolkit.getDefaultToolkit().getScreenSize().height *.5f-100), 500, 200); + } + + private String getFormattedBarText(String text) { + return String.format("%s%20s", text, ""); + } + + private void appendToPane(JTextPane tp, String msg, Color c) { + StyleContext sc = StyleContext.getDefaultStyleContext(); + AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, c); + + aset = sc.addAttribute(aset, StyleConstants.FontFamily, "Consolas"); + aset = sc.addAttribute(aset, StyleConstants.Alignment, StyleConstants.ALIGN_JUSTIFIED); + + int len = tp.getDocument().getLength(); + tp.setCaretPosition(len); + tp.setCharacterAttributes(aset, false); + tp.replaceSelection(msg); + try { + tp.setCaretPosition(tp.getText().length()-1); //WTF + } catch(Exception e) {} + } +} From b9e71455ca12be7f4e6d894c1f98eaa96ae0078a Mon Sep 17 00:00:00 2001 From: Dev Kev <69854056+DevKevYT@users.noreply.github.com> Date: Thu, 17 Sep 2020 15:17:14 +0200 Subject: [PATCH 3/7] Add files via upload --- com/devkev/gui/Window.java | 56 +++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 7 deletions(-) diff --git a/com/devkev/gui/Window.java b/com/devkev/gui/Window.java index 25088ba..aecf820 100644 --- a/com/devkev/gui/Window.java +++ b/com/devkev/gui/Window.java @@ -15,11 +15,14 @@ import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; import java.io.FileReader; +import java.io.FileWriter; import java.io.IOException; -import java.io.InputStream; import javax.swing.BorderFactory; +import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JMenu; @@ -57,6 +60,7 @@ public class Window { volatile int inputStart = 0; private static Font font; + private File openedFile = null; //Null means, creating a new file when saving. public Window() { try { @@ -85,17 +89,21 @@ public void componentHidden(ComponentEvent e) {} p.addOutput(new Output() { public void warning(String message) { console.append("[WARN]" + message + "\n"); + consolePane.getVerticalScrollBar().setValue(consolePane.getVerticalScrollBar().getMaximum()); } public void log(String message, boolean newline) { console.append(message + (newline ? "\n" : "")); + consolePane.getVerticalScrollBar().setValue(consolePane.getVerticalScrollBar().getMaximum()); } public void error(String message) { console.append(message + "\n"); + consolePane.getVerticalScrollBar().setValue(consolePane.getVerticalScrollBar().getMaximum()); } }); input = new ApplicationInput() { @Override public void awaitInput() { + System.out.println("Waiting for input..."); waitForEnter = true; console.setEnabled(true); inputStart = console.getText().length(); @@ -106,7 +114,7 @@ public void awaitInput() { p.setInput(input); p.setApplicationListener(new ApplicationListener() { public void done(int exitCode) { - runWindow.setTitle("Done (Exit Code " + exitCode + ")"); + runWindow.setTitle("Finished with Exit Code " + exitCode); window.setEnabled(true); console.setEnabled(false); } @@ -129,14 +137,17 @@ public boolean dispatchKeyEvent(KeyEvent e) { JMenu m = new JMenu("File"); JMenuItem newFile = new JMenuItem("New"); + newFile.setAccelerator(KeyStroke.getKeyStroke("control N")); newFile.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { textArea.setText(""); + openedFile = null; } }); m.add(newFile); - JMenuItem loadFile = new JMenuItem("Load File"); + JMenuItem loadFile = new JMenuItem(getFormattedBarText("Open...")); + loadFile.setAccelerator(KeyStroke.getKeyStroke("control O")); loadFile.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { window.setEnabled(false); @@ -148,11 +159,12 @@ public void actionPerformed(ActionEvent e) { BufferedReader reader = new BufferedReader(new FileReader(chooser.getSelectedFile())); String line = reader.readLine(); while(line != null) { - appendToPane(textArea, "\n" + line, Color.black); + appendToPane(textArea, line + "\n", Color.black); line = reader.readLine(); } reader.close(); window.setEnabled(true); + openedFile = chooser.getSelectedFile(); } catch (Exception e1) { e1.printStackTrace(); window.setEnabled(true); @@ -164,6 +176,29 @@ public void actionPerformed(ActionEvent e) { }); m.add(loadFile); JMenuItem saveFile = new JMenuItem("Save File"); + saveFile.setAccelerator(KeyStroke.getKeyStroke("control S")); + saveFile.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if(openedFile == null) { + if(textArea.getText().isEmpty()) return; + window.setEnabled(false); + JFileChooser chooser = new JFileChooser(); + chooser.setDialogTitle("Save new file"); + int res = chooser.showSaveDialog(new JFrame()); + if(res == JFileChooser.APPROVE_OPTION) { + BufferedWriter writer = new BufferedWriter(new FileWriter(chooser.getSelectedFile())); + try { + writer.write(textArea.getText()); + writer.close(); + } catch (IOException e1) { + e1.printStackTrace(); + } + } + window.setEnabled(true); + } else System.out.println("Overwriging file..."); + + } + }); m.add(saveFile); bar.add(m); @@ -171,7 +206,7 @@ public void actionPerformed(ActionEvent e) { bar.add(m2); JMenu m3 = new JMenu("Run"); - JMenuItem run = new JMenuItem(getFormattedBarText("Run in shell")); + JMenuItem run = new JMenuItem(getFormattedBarText("Run in Shell")); run.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0)); run.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { @@ -182,7 +217,6 @@ public void actionPerformed(ActionEvent e) { runWindow.setVisible(true); window.setEnabled(false); p.execute(textArea.getText(), true); - System.out.println("Done"); } }); m3.add(run); @@ -202,6 +236,14 @@ public void actionPerformed(ActionEvent e) { window.setSize(500, 500); } + JFrame saveDialog; + JButton approveSave; + JButton cancelSave; + + public void initSaveNotification() { + saveDialog = new JFrame("Save changes to "); + } + JFrame runWindow; JTextArea console; JScrollPane consolePane; @@ -244,7 +286,6 @@ public void componentHidden(ComponentEvent e) {} console.addCaretListener(new CaretListener() { @Override public void caretUpdate(CaretEvent e) { - System.out.println("Updating caret..."); System.out.println(console.getCaretPosition() + " " + inputStart); if(input.inputRequested() && console.getCaretPosition() < inputStart) { console.setCaretPosition(inputStart); @@ -268,6 +309,7 @@ public void keyPressed(KeyEvent e) { consolePane = new JScrollPane(console, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); consolePane.setBounds(5, 5, runWindow.getRootPane().getWidth()-10, runWindow.getRootPane().getHeight()-10); consolePane.setBorder(BorderFactory.createLineBorder(Color.BLACK)); + consolePane.setAutoscrolls(true); runWindow.add(consolePane); runWindow.pack(); From 6d634d146446395c6d6c0dee184370ca64e9c114 Mon Sep 17 00:00:00 2001 From: Dev Kev <69854056+DevKevYT@users.noreply.github.com> Date: Thu, 17 Sep 2020 16:58:06 +0200 Subject: [PATCH 4/7] Add files via upload --- .../devscript/raw/ApplicationInput.java | 2 +- com/devkev/gui/Window.java | 154 ++++++++++++++++-- 2 files changed, 142 insertions(+), 14 deletions(-) diff --git a/com/devkev/devscript/raw/ApplicationInput.java b/com/devkev/devscript/raw/ApplicationInput.java index 49da43f..5d3d41e 100644 --- a/com/devkev/devscript/raw/ApplicationInput.java +++ b/com/devkev/devscript/raw/ApplicationInput.java @@ -14,7 +14,6 @@ public abstract class ApplicationInput extends InputStream { public int read() throws IOException { if(!inputReqested) { inputReqested = true; - System.out.println("Awaiting input..."); awaitInput(); synchronized (this) { try { @@ -29,6 +28,7 @@ public int read() throws IOException { System.out.println("Fetching data... " + data.getBytes()[index-1]); return data.getBytes()[index-1]; } else { + inputReqested = false; data = ""; index = 0; return -1; diff --git a/com/devkev/gui/Window.java b/com/devkev/gui/Window.java index aecf820..d588d88 100644 --- a/com/devkev/gui/Window.java +++ b/com/devkev/gui/Window.java @@ -1,11 +1,16 @@ package com.devkev.gui; import java.awt.Color; +import java.awt.Desktop; import java.awt.Dimension; import java.awt.Font; +import java.awt.HeadlessException; import java.awt.KeyEventDispatcher; import java.awt.KeyboardFocusManager; import java.awt.Toolkit; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentEvent; @@ -20,6 +25,9 @@ import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; import javax.swing.BorderFactory; import javax.swing.JButton; @@ -61,6 +69,10 @@ public class Window { private static Font font; private File openedFile = null; //Null means, creating a new file when saving. + private static final String TITLE = "Devscript 1.9.0 Editor (pre alpha build)"; + private ArrayList history = new ArrayList(); + private int historyIndex = 0; + public int maxHistorySize = 50; public Window() { try { @@ -68,7 +80,7 @@ public Window() { } catch (Exception evt) {} font = new Font("Consolas", Font.PLAIN, 13); - window = new JFrame("Devscript 1.9.0 Editor (pre alpha build)"); + window = new JFrame(TITLE + " - unsaved"); window.setVisible(true); window.setResizable(true); window.setLayout(null); @@ -142,6 +154,7 @@ public boolean dispatchKeyEvent(KeyEvent e) { public void actionPerformed(ActionEvent e) { textArea.setText(""); openedFile = null; + window.setTitle(TITLE + " - unsaved"); } }); m.add(newFile); @@ -164,7 +177,9 @@ public void actionPerformed(ActionEvent e) { } reader.close(); window.setEnabled(true); + window.toFront(); openedFile = chooser.getSelectedFile(); + window.setTitle(TITLE); } catch (Exception e1) { e1.printStackTrace(); window.setEnabled(true); @@ -183,26 +198,60 @@ public void actionPerformed(ActionEvent e) { if(textArea.getText().isEmpty()) return; window.setEnabled(false); JFileChooser chooser = new JFileChooser(); - chooser.setDialogTitle("Save new file"); + chooser.setDialogTitle("Save New File"); int res = chooser.showSaveDialog(new JFrame()); - if(res == JFileChooser.APPROVE_OPTION) { - BufferedWriter writer = new BufferedWriter(new FileWriter(chooser.getSelectedFile())); - try { - writer.write(textArea.getText()); - writer.close(); - } catch (IOException e1) { - e1.printStackTrace(); - } - } + if(res == JFileChooser.APPROVE_OPTION) saveDocument(chooser.getSelectedFile()); window.setEnabled(true); - } else System.out.println("Overwriging file..."); - + } else saveDocument(openedFile); + window.setTitle(TITLE + " - saved"); } }); m.add(saveFile); bar.add(m); JMenu m2 = new JMenu("Edit"); + JMenuItem undo = new JMenuItem(getFormattedBarText("Undo")); + undo.setAccelerator(KeyStroke.getKeyStroke("control Z")); + undo.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if(historyIndex > 0) { + historyIndex--; + textArea.setText(history.get(historyIndex)); + if(historyIndex == 0) undo.setEnabled(false); + } + } + }); + undo.setEnabled(false); + m2.add(undo); + m2.addSeparator(); + JMenuItem selectAll = new JMenuItem(getFormattedBarText("Select All")); + selectAll.setAccelerator(KeyStroke.getKeyStroke("control A")); + selectAll.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + textArea.selectAll(); + } + }); + JMenuItem copyToClipboard = new JMenuItem(getFormattedBarText("Copy")); + copyToClipboard.setAccelerator(KeyStroke.getKeyStroke("control C")); + copyToClipboard.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(textArea.getSelectedText()),null); + } + }); + JMenuItem paste = new JMenuItem(getFormattedBarText("Paste")); + paste.setAccelerator(KeyStroke.getKeyStroke("control V")); + paste.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + try { + textArea.setText((String) Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor)); + } catch (HeadlessException | UnsupportedFlavorException | IOException e1) { + e1.printStackTrace(); + } + } + }); + m2.add(selectAll); + m2.add(copyToClipboard); + m2.add(paste); bar.add(m2); JMenu m3 = new JMenu("Run"); @@ -222,10 +271,79 @@ public void actionPerformed(ActionEvent e) { m3.add(run); bar.add(m3); + JMenu m4 = new JMenu("Help"); + JMenuItem help = new JMenuItem("Tutorial"); + help.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ProcessBuilder pb = new ProcessBuilder("Notepad.exe", "README.md"); + try { + pb.start(); + } catch (IOException e1) { + e1.printStackTrace(); + } + } + }); + m4.add(help); + JMenuItem license = new JMenuItem("License"); + license.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ProcessBuilder pb = new ProcessBuilder("Notepad.exe", "LICENSE"); + try { + pb.start(); + } catch (IOException e1) { + e1.printStackTrace(); + } + } + }); + JMenuItem changelog = new JMenuItem("Changelog"); + changelog.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ProcessBuilder pb = new ProcessBuilder("Notepad.exe", "changelog.txt"); + try { + pb.start(); + } catch (IOException e1) { + e1.printStackTrace(); + } + } + }); + m4.add(changelog); + m4.add(license); + m4.addSeparator(); + JMenuItem about = new JMenuItem("About / GitHub"); + about.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + try { + Desktop.getDesktop().browse(new URI("https://github.com/DevKevYT/devscript")); + } catch (IOException | URISyntaxException e) { + e.printStackTrace(); + } + } + }); + m4.add(about); + m4.addSeparator(); + JMenuItem ty = new JMenuItem("Thank you! <3"); + ty.setEnabled(false); + m4.add(ty); + bar.add(m4); + window.setJMenuBar(bar); textArea = new JTextPane(); textArea.setFont(font); + textArea.addKeyListener(new KeyListener() { + @Override + public void keyTyped(KeyEvent e) { + if(!e.isControlDown()) window.setTitle(TITLE + " - unsaved"); + } + public void keyReleased(KeyEvent e) { + if(e.isControlDown()) return; + history.add(textArea.getText()); + if(history.size() >= 20) history.remove(0); + historyIndex = history.size()-1; + undo.setEnabled(true); + } + public void keyPressed(KeyEvent e) {} + }); pane = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); pane.setBounds(5, 5, window.getRootPane().getWidth() - 10, window.getRootPane().getHeight()-bar.getHeight() - 10); pane.setBorder(BorderFactory.createLineBorder(Color.BLACK)); @@ -236,6 +354,16 @@ public void actionPerformed(ActionEvent e) { window.setSize(500, 500); } + private void saveDocument(File file) { + try { + BufferedWriter writer = new BufferedWriter(new FileWriter(file)); + writer.write(textArea.getText()); + writer.close(); + } catch (IOException e1) { + e1.printStackTrace(); + } + } + JFrame saveDialog; JButton approveSave; JButton cancelSave; From 0cbe544634b64090fc5dc508ed5fec9a2f25b006 Mon Sep 17 00:00:00 2001 From: Dev Kev <69854056+DevKevYT@users.noreply.github.com> Date: Fri, 18 Sep 2020 09:41:44 +0200 Subject: [PATCH 5/7] Add files via upload --- com/devkev/gui/Window.java | 39 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/com/devkev/gui/Window.java b/com/devkev/gui/Window.java index d588d88..a859927 100644 --- a/com/devkev/gui/Window.java +++ b/com/devkev/gui/Window.java @@ -28,11 +28,15 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; +import java.util.Enumeration; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JFrame; +import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; @@ -51,6 +55,7 @@ import com.devkev.devscript.raw.ApplicationInput; import com.devkev.devscript.raw.ApplicationListener; +import com.devkev.devscript.raw.ConsoleMain; import com.devkev.devscript.raw.Output; import com.devkev.devscript.raw.Process; @@ -74,6 +79,8 @@ public class Window { private int historyIndex = 0; public int maxHistorySize = 50; + JLabel commandPreview; + public Window() { try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); @@ -148,7 +155,7 @@ public boolean dispatchKeyEvent(KeyEvent e) { JMenu m = new JMenu("File"); - JMenuItem newFile = new JMenuItem("New"); + JMenuItem newFile = new JMenuItem("New..."); newFile.setAccelerator(KeyStroke.getKeyStroke("control N")); newFile.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { @@ -158,6 +165,8 @@ public void actionPerformed(ActionEvent e) { } }); m.add(newFile); + m.addSeparator(); + JMenuItem loadFile = new JMenuItem(getFormattedBarText("Open...")); loadFile.setAccelerator(KeyStroke.getKeyStroke("control O")); @@ -190,7 +199,7 @@ public void actionPerformed(ActionEvent e) { } }); m.add(loadFile); - JMenuItem saveFile = new JMenuItem("Save File"); + JMenuItem saveFile = new JMenuItem("Save File..."); saveFile.setAccelerator(KeyStroke.getKeyStroke("control S")); saveFile.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { @@ -349,6 +358,32 @@ public void keyPressed(KeyEvent e) {} pane.setBorder(BorderFactory.createLineBorder(Color.BLACK)); window.add(pane); + commandPreview = new JLabel("This is a test"); + commandPreview.setBorder(BorderFactory.createLineBorder(Color.black, 2)); + commandPreview.setBackground(Color.lightGray); + commandPreview.setBounds(20, 20, 100, 40); + commandPreview.setLocation(30, 30); + commandPreview.addKeyListener(new KeyListener() { + @Override + public void keyTyped(KeyEvent e) { + + } + + @Override + public void keyReleased(KeyEvent e) { + } + + @Override + public void keyPressed(KeyEvent e) { + System.out.println(e.getKeyCode()); + if(e.isControlDown() && e.getKeyCode() == KeyEvent.VK_SPACE) { + System.out.println("PReview!"); + } + } + }); + commandPreview.setVisible(true); + window.add(commandPreview); + initRunWindow(); window.pack(); window.setSize(500, 500); From 42817a9075433a3b6638afb6e449ede77ebe70d2 Mon Sep 17 00:00:00 2001 From: Dev Kev <69854056+DevKevYT@users.noreply.github.com> Date: Fri, 18 Sep 2020 15:03:53 +0200 Subject: [PATCH 6/7] Add files via upload --- ConsoleMain.java | 99 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 ConsoleMain.java diff --git a/ConsoleMain.java b/ConsoleMain.java new file mode 100644 index 0000000..9a6c06e --- /dev/null +++ b/ConsoleMain.java @@ -0,0 +1,99 @@ +package com.devkev.devscript.raw; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URLDecoder; + +import com.devkev.gui.Window; + +/**@author Philipp Gersch + * @version 1.8.2 (stable) + * Valid arguments are:
-e or --execute [some code] - Executes the String
+ * -f or --file [path] - Reads the file and executes the code from it.
+ * If no argument was passed, the default Editor GUI will open.*/ +public class ConsoleMain { + + /*Argument schema: -f -e --nogui + * When nogui is not given, the gui program will start with the given script from the command line + * */ + + public static void main(String[] args) throws IOException { + boolean initGUI = true; + String scriptToExecute = null; + String filePath = null; + //ALL arguments need to be checked + + for(int i = 0; i < args.length; i++) { + if((args[i].equals("-e") || args[i].equals("--execute")) && scriptToExecute == null) { + if(i + 1 < args.length) { + if(!isArgument(args[i+1])) { + scriptToExecute = args[i+1]; + i++; //Skip the next iteration + continue; + } + } + throw new IllegalArgumentException("Expecting string after " + args[i] + " [script_to_execute]"); + } else if((args[i].equals("-f") || args[i].equals("--file")) && filePath == null) { + if(i + 1 < args.length) { + if(!isArgument(args[i+1])) { + filePath = args[i+1]; + i++; + continue; + } + } + throw new IllegalArgumentException("Expecting string after " + args[i] + " [path_to_file]"); + } else if(args[i].equals("--nogui")) { + initGUI = false; + continue; + } + throw new IllegalArgumentException("Unknown argument " + args[i] + "Valid arguments are:\n-f or --file\tOpens the file in the editor (If --nogui is set, the file is executed)\n-e or --execute\tOpens the script with the editor (If --nogui is set, the script is executed)\n--nogui\tOpens the command line editor"); + } + + System.out.println("InitGUI? " + initGUI + "\n" + "Script zo execute? " + scriptToExecute + "\nFilePath? " + filePath); + return; + //Apply rules + +// Process p = new Process(true); +// p.addSystemOutput(); +// p.setInput(System.in); +// +// if(args.length == 0) { +// if(ConsoleMain.class.getResourceAsStream("/Editor.txt") == null) { +// System.err.println("Editor file is missing at: " + URLDecoder.decode(ConsoleMain.class.getProtectionDomain().getCodeSource().getLocation().getPath(), "UTF-8")); +// return; +// } +// BufferedReader reader = new BufferedReader(new InputStreamReader(ConsoleMain.class.getResourceAsStream("/Editor.txt"))); +// String code = ""; +// String line = reader.readLine(); +// while(line != null) { +// code += line; +// line = reader.readLine(); +// } +// reader.close(); +// p.execute(code, false); +// return; +// } +// +// if(args[0].equals("-e") || args[0].equals("--execute")) { +// if(args.length < 2) { +// System.err.println("Argument " + args[0] + " expects an executable script, e.g.: -e \"println \"Hello World;\"\""); +// System.exit(-1); +// } +// p.execute(args[1], true); +// } else if(args[0].equals("-f") || args[0].equals("--file")) { +// if(args.length < 2) { +// System.err.println("Argument " + args[0] + " expects a path to a text file containing the script"); +// System.exit(-1); +// } +// p.execute(new File(args[1]), true); +// } else if(args[0].equals("--gui") || args[0].equals("-g")) { +// new Window(); +// } + } + + private static boolean isArgument(String arg) { + return arg.equals("-f") || arg.equals("--file") || arg.equals("-e") || arg.equals("--execute") || arg.equals("--nogui"); + } +} From c06fb74599aa04f2327a2d8eee13cacb0d5e13c2 Mon Sep 17 00:00:00 2001 From: Dev Kev <69854056+DevKevYT@users.noreply.github.com> Date: Mon, 21 Sep 2020 16:10:28 +0200 Subject: [PATCH 7/7] Add files via upload Added GUI --- .../devscript/raw/ApplicationInput.java | 1 - com/devkev/devscript/raw/ConsoleMain.java | 98 +++++--- com/devkev/devscript/raw/Process.java | 3 +- com/devkev/gui/Window.java | 235 ++++++++++++++---- 4 files changed, 252 insertions(+), 85 deletions(-) diff --git a/com/devkev/devscript/raw/ApplicationInput.java b/com/devkev/devscript/raw/ApplicationInput.java index 5d3d41e..0f35c94 100644 --- a/com/devkev/devscript/raw/ApplicationInput.java +++ b/com/devkev/devscript/raw/ApplicationInput.java @@ -25,7 +25,6 @@ public int read() throws IOException { } index++; if(index < data.length() && !data.isEmpty()) { - System.out.println("Fetching data... " + data.getBytes()[index-1]); return data.getBytes()[index-1]; } else { inputReqested = false; diff --git a/com/devkev/devscript/raw/ConsoleMain.java b/com/devkev/devscript/raw/ConsoleMain.java index 03d1973..c0b7491 100644 --- a/com/devkev/devscript/raw/ConsoleMain.java +++ b/com/devkev/devscript/raw/ConsoleMain.java @@ -14,42 +14,80 @@ * -f or --file [path] - Reads the file and executes the code from it.
* If no argument was passed, the default Editor GUI will open.*/ public class ConsoleMain { + + /*Argument schema: -f -e --nogui + * When nogui is not given, the gui program will start with the given script from the command line + * */ + public static void main(String[] args) throws IOException { - Process p = new Process(true); - p.addSystemOutput(); - p.setInput(System.in); - - if(args.length == 0) { - if(ConsoleMain.class.getResourceAsStream("/Editor.txt") == null) { - System.err.println("Editor file is missing at: " + URLDecoder.decode(ConsoleMain.class.getProtectionDomain().getCodeSource().getLocation().getPath(), "UTF-8")); - return; - } - BufferedReader reader = new BufferedReader(new InputStreamReader(ConsoleMain.class.getResourceAsStream("/Editor.txt"))); - String code = ""; - String line = reader.readLine(); - while(line != null) { - code += line; - line = reader.readLine(); + boolean initGUI = true; + String scriptToExecute = null; + String filePath = null; + //ALL arguments need to be checked + + for(int i = 0; i < args.length; i++) { + if((args[i].equals("-e") || args[i].equals("--execute")) && scriptToExecute == null) { + if(i + 1 < args.length) { + if(!isArgument(args[i+1])) { + scriptToExecute = args[i+1]; + i++; //Skip the next iteration + continue; + } + } + throw new IllegalArgumentException("Expecting string after " + args[i] + " [script_to_execute]"); + } else if((args[i].equals("-f") || args[i].equals("--file")) && filePath == null) { + if(i + 1 < args.length) { + if(!isArgument(args[i+1])) { + filePath = args[i+1]; + i++; + continue; + } + } + throw new IllegalArgumentException("Expecting string after " + args[i] + " [path_to_file]"); + } else if(args[i].equals("--nogui")) { + initGUI = false; + continue; } - reader.close(); - p.execute(code, false); - return; + System.out.println("Valid arguments are:\n-f | --file\tOpens the file in the editor (If --nogui is set, the file is executed)\n-e | --execute\tOpens the script with the editor (If --nogui is set, the script is executed)\n | --nogui\tOpens the command line editor"); + throw new IllegalArgumentException("Unknown argument " + args[i] ); } - if(args[0].equals("-e") || args[0].equals("--execute")) { - if(args.length < 2) { - System.err.println("Argument " + args[0] + " expects an executable script, e.g.: -e \"println \"Hello World;\"\""); - System.exit(-1); + if(initGUI) { + Window w = new Window(); + if(filePath != null) { + w.openDocument(new File(filePath)); + } else if(scriptToExecute != null) { + w.setScript(scriptToExecute); } - p.execute(args[1], true); - } else if(args[0].equals("-f") || args[0].equals("--file")) { - if(args.length < 2) { - System.err.println("Argument " + args[0] + " expects a path to a text file containing the script"); - System.exit(-1); + } else { + Process p = new Process(true); + p.addSystemOutput(); + p.setInput(System.in); + + if(filePath != null) { + p.execute(new File(args[1]), true); + } else if(scriptToExecute != null) { + p.execute(args[1], true); + } else { + if(ConsoleMain.class.getResourceAsStream("/Editor.txt") == null) { + System.err.println("Editor file is missing at: " + URLDecoder.decode(ConsoleMain.class.getProtectionDomain().getCodeSource().getLocation().getPath(), "UTF-8")); + return; + } + BufferedReader reader = new BufferedReader(new InputStreamReader(ConsoleMain.class.getResourceAsStream("/Editor.txt"))); + String code = ""; + String line = reader.readLine(); + while(line != null) { + code += line; + line = reader.readLine(); + } + reader.close(); + p.execute(code, false); + return; } - p.execute(new File(args[1]), true); - } else if(args[0].equals("--gui") || args[0].equals("-g")) { - new Window(); } } + + private static boolean isArgument(String arg) { + return arg.equals("-f") || arg.equals("--file") || arg.equals("-e") || arg.equals("--execute") || arg.equals("--nogui"); + } } diff --git a/com/devkev/devscript/raw/Process.java b/com/devkev/devscript/raw/Process.java index f35deb2..47adb1a 100644 --- a/com/devkev/devscript/raw/Process.java +++ b/com/devkev/devscript/raw/Process.java @@ -33,7 +33,7 @@ public class Process { public long maxRuntime = 0; //Runtime in ms. If < 0, runtime is infinite private long start = 0; - public final String version = "1.8.3"; + public final String version = "1.9.0"; /**The file, the script is executed from. May be null. Just useful for some Native commands*/ public File file = null; @@ -106,6 +106,7 @@ public Thread execute(String script, boolean newThread) { script = script.replaceAll("\t", ""); script = script.replaceAll("\r", ""); + script = script.replaceAll("\n", " "); main = new Block(new StringBuilder(script), null); main.thread = null; diff --git a/com/devkev/gui/Window.java b/com/devkev/gui/Window.java index a859927..ceb0d97 100644 --- a/com/devkev/gui/Window.java +++ b/com/devkev/gui/Window.java @@ -28,18 +28,17 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; -import java.util.Enumeration; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; +import javax.swing.JLayeredPane; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; +import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextPane; @@ -55,7 +54,6 @@ import com.devkev.devscript.raw.ApplicationInput; import com.devkev.devscript.raw.ApplicationListener; -import com.devkev.devscript.raw.ConsoleMain; import com.devkev.devscript.raw.Output; import com.devkev.devscript.raw.Process; @@ -74,11 +72,13 @@ public class Window { private static Font font; private File openedFile = null; //Null means, creating a new file when saving. - private static final String TITLE = "Devscript 1.9.0 Editor (pre alpha build)"; + private static final String TITLE = "Devscript 1.9.0 Editor (Alpha)"; private ArrayList history = new ArrayList(); private int historyIndex = 0; public int maxHistorySize = 50; + JLayeredPane layerPane; + JPanel previewContainer; JLabel commandPreview; public Window() { @@ -96,6 +96,7 @@ public Window() { public void componentResized(ComponentEvent e) { if(textArea == null) return; pane.setSize(window.getRootPane().getWidth() - 10, window.getRootPane().getHeight()-bar.getHeight() - 10); + layerPane.setSize(window.getRootPane().getWidth() - 10, window.getRootPane().getHeight()-bar.getHeight() - 10); pane.updateUI(); } public void componentShown(ComponentEvent e) {} @@ -122,7 +123,6 @@ public void error(String message) { input = new ApplicationInput() { @Override public void awaitInput() { - System.out.println("Waiting for input..."); waitForEnter = true; console.setEnabled(true); inputStart = console.getText().length(); @@ -148,6 +148,42 @@ public boolean dispatchKeyEvent(KeyEvent e) { console.setCaretColor(Color.black); } return false; +// if(window.isEnabled() && e.isControlDown() && e.getKeyCode() == KeyEvent.VK_SPACE) { +// String commandSnippet = textArea.getText(); +// for(int i = textArea.getCaretPosition(); i >= 0; i--) { +// char current = textArea.getText().charAt(i); +// System.out.println("CHecking: '" + current + "'"); +// if(current == ' ' || current == '\n' || current == '\t' || current == '\r' || Alphabet.partOf(current) || i == 0) { +// System.out.println((i+1) + " " + textArea.getCaretPosition()); +// commandSnippet = textArea.getText().substring(i == 0 ? i : i+1, textArea.getCaretPosition()).trim(); +// System.out.println("Snippet: " + commandSnippet); +// break; +// } +// } +// if(!commandSnippet.isEmpty()) { +// commandPreview.setVisible(true); +// commandPreview.setLocation(textArea.getCaret().getMagicCaretPosition().x + 5, textArea.getCaret().getMagicCaretPosition().y + 25); +// +// StringBuilder html = new StringBuilder(""); +// for(GeneratedLibrary lib : p.getLibraries()) { +// for(Command c : lib.commands) { +// if(c.name.length() >= commandSnippet.length()) { +// if(c.name.substring(0, commandSnippet.length()).equals(commandSnippet)) { +// String args = ""; +// for(DataType s : c.arguments) { +// args += "[" + s.type + "] "; +// } +// html.append(c.name + " " + args + "
"); +// } +// } +// } +// } +// html.append(""); +// System.out.println(html); +// commandPreview.setText(html.toString()); +// } +// } +// return false; } }); @@ -165,8 +201,6 @@ public void actionPerformed(ActionEvent e) { } }); m.add(newFile); - m.addSeparator(); - JMenuItem loadFile = new JMenuItem(getFormattedBarText("Open...")); loadFile.setAccelerator(KeyStroke.getKeyStroke("control O")); @@ -176,23 +210,7 @@ public void actionPerformed(ActionEvent e) { JFileChooser chooser = new JFileChooser(); int res = chooser.showOpenDialog(new JFrame()); if(res == JFileChooser.APPROVE_OPTION) { - try { - textArea.setText(""); - BufferedReader reader = new BufferedReader(new FileReader(chooser.getSelectedFile())); - String line = reader.readLine(); - while(line != null) { - appendToPane(textArea, line + "\n", Color.black); - line = reader.readLine(); - } - reader.close(); - window.setEnabled(true); - window.toFront(); - openedFile = chooser.getSelectedFile(); - window.setTitle(TITLE); - } catch (Exception e1) { - e1.printStackTrace(); - window.setEnabled(true); - } + openDocument(chooser.getSelectedFile()); } else { window.setEnabled(true); } @@ -216,6 +234,90 @@ public void actionPerformed(ActionEvent e) { } }); m.add(saveFile); + m.addSeparator(); + JMenu examples = new JMenu("Examples"); + + JMenuItem selectionSort = new JMenuItem("Selection Sort"); + selectionSort.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + openDocument(null); + textArea.setText("#Selection sort example by DevKev#\r\n" + + "\r\n" + + "unsorted = [3 4 7 8 9 543 23 7 5 32 1 56 7 65 34 13 5 7 2];\r\n" + + "sorted = [];\r\n" + + "record = 99999;\r\n" + + "index = -1;\r\n" + + "\r\n" + + "loop" + + " {\r\n" + + " for i (length $unsorted) \r\n" + + " {\r\n" + + " if ($unsorted[$i] lt $record) \r\n" + + " {\r\n" + + " record = $unsorted[$i];\r\n" + + " index = $i;\r\n" + + " };\r\n" + + " };\r\n" + + "\r\n" + + " push $unsorted[$index] $sorted;\r\n" + + " pop $unsorted $index;\r\n" + + " record = 99999;\r\n" + + " \r\n" + + " if ((length $unsorted) == 0) \r\n" + + " {\r\n" + + " break;\r\n" + + " };\r\n" + + "};\r\n" + + "\r\n" + + "println \"Done\";\r\n" + + "println $sorted;"); + } + }); + examples.add(selectionSort); + + JMenuItem calculator = new JMenuItem("Calculator"); + calculator.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + openDocument(null); + textArea.setText("#Simple calculator with input#\r\n" + + "#Should also be an example for functions#\r\n" + + "\r\n" + + "calculate = {\r\n" + + " num1 = $0; #Better names#\r\n" + + " num2 = $1;\r\n" + + " operator = $2;\r\n" + + "\r\n" + + " ifnot (($num1 typeof num) or ($num2 typeof num))\r\n" + + " {\r\n" + + " println \"Error\";\r\n" + + " return;\r\n" + + " };\r\n" + + "\r\n" + + " if ($operator == +)\r\n" + + " {\r\n" + + " return ($num1 + $num2);\r\n" + + " };\r\n" + + " if ($operator == -) \r\n" + + " { \r\n" + + " return ($num1 - $num2);\r\n" + + " };\r\n" + + " println \"Error, unknown operator: \" $operator;\r\n" + + "};\r\n" + + "\r\n" + + "print \"Enter first number: \";\r\n" + + "num1 = (input);\r\n" + + "print \"Enter second number: \";\r\n" + + "num2 = (input);\r\n" + + "print \"Enter operator (+, -): \";\r\n" + + "operator = (input);\r\n" + + "\r\n" + + "println \"Calculating...\";\r\n" + + "println (call $calculate $num1 $num2 $operator);"); + } + }); + examples.add(calculator); + + m.add(examples); bar.add(m); JMenu m2 = new JMenu("Edit"); @@ -281,6 +383,17 @@ public void actionPerformed(ActionEvent e) { bar.add(m3); JMenu m4 = new JMenu("Help"); + JMenuItem commandCC = new JMenuItem("Command Cheatsheet"); + commandCC.setToolTipText("Runs the 'help' command"); + commandCC.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if(p.isRunning()) return; + console.setText(""); + runWindow.toFront(); + runWindow.setVisible(true); + p.execute("help", false); + }}); + m4.add(commandCC); JMenuItem help = new JMenuItem("Tutorial"); help.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { @@ -339,10 +452,12 @@ public void actionPerformed(ActionEvent arg0) { textArea = new JTextPane(); textArea.setFont(font); + textArea.setLayout(null); textArea.addKeyListener(new KeyListener() { @Override public void keyTyped(KeyEvent e) { if(!e.isControlDown()) window.setTitle(TITLE + " - unsaved"); + commandPreview.setVisible(false); } public void keyReleased(KeyEvent e) { if(e.isControlDown()) return; @@ -356,44 +471,59 @@ public void keyPressed(KeyEvent e) {} pane = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); pane.setBounds(5, 5, window.getRootPane().getWidth() - 10, window.getRootPane().getHeight()-bar.getHeight() - 10); pane.setBorder(BorderFactory.createLineBorder(Color.BLACK)); - window.add(pane); - commandPreview = new JLabel("This is a test"); - commandPreview.setBorder(BorderFactory.createLineBorder(Color.black, 2)); - commandPreview.setBackground(Color.lightGray); - commandPreview.setBounds(20, 20, 100, 40); - commandPreview.setLocation(30, 30); - commandPreview.addKeyListener(new KeyListener() { - @Override - public void keyTyped(KeyEvent e) { - - } - - @Override - public void keyReleased(KeyEvent e) { - } - - @Override - public void keyPressed(KeyEvent e) { - System.out.println(e.getKeyCode()); - if(e.isControlDown() && e.getKeyCode() == KeyEvent.VK_SPACE) { - System.out.println("PReview!"); - } - } - }); - commandPreview.setVisible(true); - window.add(commandPreview); + commandPreview = new JLabel("println [STRING]
print [STRING]"); + commandPreview.setBorder(BorderFactory.createLineBorder(Color.black, 1)); + commandPreview.setOpaque(true); + commandPreview.setVisible(false); + commandPreview.setForeground(Color.darkGray); + commandPreview.setFont(new Font("Arial", Font.BOLD, 11)); + commandPreview.setBounds(0, 0, 200, 60); + + layerPane = new JLayeredPane(); + layerPane.add(pane); + layerPane.add(commandPreview); + layerPane.setLayer(commandPreview, 999); + window.add(layerPane); initRunWindow(); window.pack(); window.setSize(500, 500); } - private void saveDocument(File file) { + public void setScript(String script) { + appendToPane(textArea, script, Color.black); + } + + public void openDocument(File file) { + try { + history.clear(); + textArea.setText(""); + if(file != null) { + BufferedReader reader = new BufferedReader(new FileReader(file)); + String line = reader.readLine(); + while(line != null) { + appendToPane(textArea, line + "\n", Color.black); + line = reader.readLine(); + } + reader.close(); + } + window.setEnabled(true); + window.toFront(); + openedFile = file; + window.setTitle(TITLE); + } catch (Exception e1) { + e1.printStackTrace(); + window.setEnabled(true); + } + } + + public void saveDocument(File file) { try { BufferedWriter writer = new BufferedWriter(new FileWriter(file)); writer.write(textArea.getText()); writer.close(); + openedFile = file; } catch (IOException e1) { e1.printStackTrace(); } @@ -449,7 +579,6 @@ public void componentHidden(ComponentEvent e) {} console.addCaretListener(new CaretListener() { @Override public void caretUpdate(CaretEvent e) { - System.out.println(console.getCaretPosition() + " " + inputStart); if(input.inputRequested() && console.getCaretPosition() < inputStart) { console.setCaretPosition(inputStart); }