Files
APOS/Scripts/JSONgui.java
T

285 lines
7.9 KiB
Java

import com.aposbot.Constants;
import com.aposbot.StandardCloseHandler;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
public final class JSONgui
implements ActionListener {
private final ScriptEngineManager manager = new ScriptEngineManager();
private TextArea editor;
private Frame frame;
private final String script_name;
private final Object config;
private final String[] help_contents;
private final Runnable completion;
public JSONgui(String script, Object config, String[] help, Runnable completion) {
this.script_name = script;
this.config = config;
this.help_contents = help;
this.completion = completion;
}
public void showFrame() {
editor = new TextArea(create_json(config), 0, 0,
TextArea.SCROLLBARS_VERTICAL_ONLY);
editor.setFont(new Font("Monospaced", Font.PLAIN, 12));
Menu file = new Menu("File");
file.add(menu_item("Save"));
file.add(menu_item("Load"));
file.addSeparator();
file.add(menu_item("Exit"));
Menu edit = new Menu("Edit");
edit.add(menu_item("Cut"));
edit.add(menu_item("Copy"));
edit.add(menu_item("Paste"));
edit.add(menu_item("Select all"));
edit.addSeparator();
edit.add(menu_item("Reset (safety net)"));
Menu help = new Menu("Help");
help.add(menu_item("Help for " + script_name));
help.add(menu_item("About"));
MenuBar bar = new MenuBar();
bar.add(file);
bar.add(edit);
bar.add(help);
Button done = new Button("Done");
done.addActionListener(this);
Panel button_pane = new Panel();
button_pane.add(done);
frame = new Frame("Configure " + script_name);
frame.setMenuBar(bar);
frame.addWindowListener(
new StandardCloseHandler(frame, StandardCloseHandler.DISPOSE)
);
frame.setIconImages(Constants.ICONS);
frame.add(editor, BorderLayout.CENTER);
frame.add(button_pane, BorderLayout.SOUTH);
frame.setSize(500, 400);
show_window(frame, null);
}
// JSON.stringify() == broken for java primitives
// so, this hack is currently required
private static final String create_json(Object object) {
StringBuilder b = new StringBuilder("{\n");
Field[] fields = object.getClass().getFields();
for (int i = 0; i < fields.length; ++i) {
Field f = fields[i];
int mod = f.getModifiers();
if ((mod & Modifier.FINAL) != 0 || (mod & Modifier.PUBLIC) == 0) {
continue;
}
String property_name = f.getName();
Class<?> c = f.getType();
b.append("\t\"");
b.append(property_name);
b.append("\": ");
try {
if (Object[].class.isAssignableFrom(c)) {
b.append(Arrays.deepToString((Object[]) f.get(object)));
} else if (c.equals(int[].class)) {
b.append(Arrays.toString((int[]) f.get(object)));
} else if (c.equals(boolean[].class)) {
b.append(Arrays.toString((boolean[]) f.get(object)));
} else if (c.equals(long[].class)) {
b.append(Arrays.toString((long[]) f.get(object)));
} else if (c.equals(char[].class)) {
b.append(Arrays.toString((char[]) f.get(object)));
} else if (c.equals(byte[].class)) {
b.append(Arrays.toString((byte[]) f.get(object)));
} else if (c.equals(short[].class)) {
b.append(Arrays.toString((short[]) f.get(object)));
} else if (c.equals(float[].class)) {
b.append(Arrays.toString((float[]) f.get(object)));
} else if (c.equals(double[].class)) {
b.append(Arrays.toString((double[]) f.get(object)));
} else if (CharSequence.class.isAssignableFrom(c)) {
b.append('"');
b.append(f.get(object).toString());
b.append('"');
} else {
b.append(f.get(object).toString());
}
} catch (Throwable t) {
b.append("ERROR");
}
if (i != (fields.length - 1)) {
b.append(",\n");
} else {
b.append("\n");
}
}
b.append("}");
return b.toString();
}
private MenuItem menu_item(String str) {
MenuItem item = new MenuItem(str);
item.addActionListener(this);
return item;
}
private static void show_window(Window w, Window parent) {
w.setLocationRelativeTo(parent);
w.toFront();
w.requestFocus();
w.setVisible(true);
}
private static void set_clipbard(String str) {
try {
StringSelection sel = new StringSelection(str);
Toolkit.getDefaultToolkit()
.getSystemClipboard().setContents(sel, null);
} catch (Throwable t) {
System.out.println("Couldn't set clipboard contents: " + t);
}
}
@Override
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
if (cmd.equals("Done")) {
try {
ScriptEngine engine = manager.getEngineByExtension("js");
engine.put("text", editor.getText());
engine.put("config", config);
engine.eval("var o = JSON.parse(text);"
+ "\nfor (var p in o) {"
+ "\n config[p] = o[p];"
+ "\n}");
frame.dispose();
if (completion != null) {
completion.run();
}
} catch (Throwable t) {
System.out.println("Error processing config: " + t);
t.printStackTrace();
}
} else if (cmd.equals("Save")) {
FileDialog d = new FileDialog(frame, "Save configuration", FileDialog.SAVE);
d.setFile(script_name + ".json");
d.setIconImages(Constants.ICONS);
show_window(d, frame);
String dir = d.getDirectory();
String file = d.getFile();
if (dir != null && file != null) {
try {
Files.write(Paths.get(dir + file),
editor.getText().getBytes(Constants.UTF_8));
} catch (Throwable t) {
System.out.println("Write error: " + t);
}
}
} else if (cmd.equals("Load")) {
FileDialog d = new FileDialog(frame, "Load configuration", FileDialog.LOAD);
d.setFile(script_name + ".json");
d.setIconImages(Constants.ICONS);
show_window(d, frame);
String dir = d.getDirectory();
String file = d.getFile();
if (dir != null && file != null) {
try {
editor.setText(new String(
Files.readAllBytes(Paths.get(dir + file)),
Constants.UTF_8));
} catch (Throwable t) {
System.out.println("Read error: " + t);
}
}
} else if (cmd.equals("Cut")) {
String str = editor.getText();
String start = str.substring(0, editor.getSelectionStart());
String end = str.substring(editor.getSelectionEnd());
set_clipbard(editor.getSelectedText());
editor.setText(start + end);
} else if (cmd.equals("Copy")) {
set_clipbard(editor.getSelectedText());
} else if (cmd.equals("Paste")) {
try {
editor.append((String) Toolkit.getDefaultToolkit()
.getSystemClipboard().getContents(editor)
.getTransferData(DataFlavor.stringFlavor));
} catch (Throwable t) {
System.out.println("Couldn't paste: " + t);
}
} else if (cmd.equals("Select all")) {
String str = editor.getText();
editor.select(0, str.length());
} else if (cmd.startsWith("Reset")) {
editor.setText(create_json(config));
} else if (cmd.startsWith("Help")) {
StringBuilder b = new StringBuilder();
if (help_contents != null) {
for (String str : help_contents) {
b.append(str);
b.append('\n');
}
}
TextArea t = new TextArea(b.toString(), 0, 0,
TextArea.SCROLLBARS_VERTICAL_ONLY);
t.setEditable(false);
final Dialog d = new Dialog(frame, "Script configuration help");
d.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
d.dispose();
}
});
d.setIconImages(Constants.ICONS);
d.add(t, BorderLayout.CENTER);
d.setSize(500, 400);
show_window(d, frame);
} else if (cmd.equals("About")) {
System.out.println("JSON script config editor by S");
} else if (cmd.equals("Exit")) {
frame.dispose();
} else {
System.out.println("unrecognized: " + cmd);
}
}
}