From c5bd92cb0f4aa311e8eaaf0a511c04dac31fc232 Mon Sep 17 00:00:00 2001 From: Victor Date: Fri, 29 Jul 2016 18:43:06 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D1=8C=20forms?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/annimon/ownlang/lib/Converters.java | 130 ++++++++++++++ .../annimon/ownlang/lib/modules/forms.java | 91 ++++++++++ .../functions/forms/ComponentValue.java | 162 ++++++++++++++++++ .../modules/functions/forms/Components.java | 52 ++++++ .../functions/forms/ContainerValue.java | 81 +++++++++ .../modules/functions/forms/JButtonValue.java | 38 ++++ .../functions/forms/JComponentValue.java | 21 +++ .../modules/functions/forms/JFrameValue.java | 28 +++ .../modules/functions/forms/JLabelValue.java | 36 ++++ .../modules/functions/forms/JPanelValue.java | 17 ++ .../functions/forms/JTextFieldValue.java | 53 ++++++ .../functions/forms/LayoutManagerValue.java | 14 ++ .../functions/forms/LayoutManagers.java | 100 +++++++++++ 13 files changed, 823 insertions(+) create mode 100644 src/main/java/com/annimon/ownlang/lib/Converters.java create mode 100644 src/main/java/com/annimon/ownlang/lib/modules/forms.java create mode 100644 src/main/java/com/annimon/ownlang/lib/modules/functions/forms/ComponentValue.java create mode 100644 src/main/java/com/annimon/ownlang/lib/modules/functions/forms/Components.java create mode 100644 src/main/java/com/annimon/ownlang/lib/modules/functions/forms/ContainerValue.java create mode 100644 src/main/java/com/annimon/ownlang/lib/modules/functions/forms/JButtonValue.java create mode 100644 src/main/java/com/annimon/ownlang/lib/modules/functions/forms/JComponentValue.java create mode 100644 src/main/java/com/annimon/ownlang/lib/modules/functions/forms/JFrameValue.java create mode 100644 src/main/java/com/annimon/ownlang/lib/modules/functions/forms/JLabelValue.java create mode 100644 src/main/java/com/annimon/ownlang/lib/modules/functions/forms/JPanelValue.java create mode 100644 src/main/java/com/annimon/ownlang/lib/modules/functions/forms/JTextFieldValue.java create mode 100644 src/main/java/com/annimon/ownlang/lib/modules/functions/forms/LayoutManagerValue.java create mode 100644 src/main/java/com/annimon/ownlang/lib/modules/functions/forms/LayoutManagers.java diff --git a/src/main/java/com/annimon/ownlang/lib/Converters.java b/src/main/java/com/annimon/ownlang/lib/Converters.java new file mode 100644 index 0000000..e0dc686 --- /dev/null +++ b/src/main/java/com/annimon/ownlang/lib/Converters.java @@ -0,0 +1,130 @@ +package com.annimon.ownlang.lib; + +/** + * Wrapper functions and interfaces. + */ +public final class Converters { + + public interface VoidToVoidFunction { + void apply(); + } + + public interface VoidToBooleanFunction { + boolean apply(); + } + + public interface VoidToIntFunction { + int apply(); + } + + public interface VoidToFloatFunction { + float apply(); + } + + public interface VoidToStringFunction { + String apply(); + } + + public interface BooleanToVoidFunction { + void apply(boolean b); + } + + public interface IntToVoidFunction { + void apply(int i); + } + + public interface FloatToVoidFunction { + void apply(float f); + } + + public interface Float4ToVoidFunction { + void apply(float f1, float f2, float f3, float f4); + } + + public interface StringToVoidFunction { + void apply(String s); + } + + + public static FunctionValue voidToVoid(VoidToVoidFunction f) { + return new FunctionValue(args -> { + f.apply(); + return NumberValue.ZERO; + }); + } + + public static FunctionValue voidToBoolean(VoidToBooleanFunction f) { + return new FunctionValue(args -> NumberValue.fromBoolean(f.apply())); + } + + public static FunctionValue voidToInt(VoidToIntFunction f) { + return new FunctionValue(args -> NumberValue.of(f.apply())); + } + + public static FunctionValue voidToFloat(VoidToFloatFunction f) { + return new FunctionValue(args -> NumberValue.of(f.apply())); + } + + public static FunctionValue voidToString(VoidToStringFunction f) { + return new FunctionValue(args -> new StringValue(f.apply())); + } + + public static FunctionValue booleanToVoid(BooleanToVoidFunction f) { + return new FunctionValue(args -> { + Arguments.check(1, args.length); + f.apply(args[0].asInt() != 0); + return NumberValue.ZERO; + }); + } + + public static FunctionValue booleanOptToVoid(BooleanToVoidFunction f) { + return booleanOptToVoid(f, true); + } + public static FunctionValue booleanOptToVoid(BooleanToVoidFunction f, final boolean def) { + return new FunctionValue(args -> { + Arguments.checkOrOr(0, 1, args.length); + f.apply( (args.length == 1) ? (args[0].asInt() != 0) : def ); + return NumberValue.ZERO; + }); + } + + public static FunctionValue intToVoid(IntToVoidFunction f) { + return new FunctionValue(args -> { + Arguments.check(1, args.length); + f.apply(args[0].asInt()); + return NumberValue.ZERO; + }); + } + + public static FunctionValue floatToVoid(FloatToVoidFunction f) { + return new FunctionValue(args -> { + Arguments.check(1, args.length); + f.apply(getNumber(args[0]).floatValue()); + return NumberValue.ZERO; + }); + } + + public static FunctionValue float4ToVoid(Float4ToVoidFunction f) { + return new FunctionValue(args -> { + Arguments.check(4, args.length); + f.apply(getNumber(args[0]).floatValue(), + getNumber(args[1]).floatValue(), + getNumber(args[2]).floatValue(), + getNumber(args[3]).floatValue()); + return NumberValue.ZERO; + }); + } + + public static FunctionValue stringToVoid(StringToVoidFunction f) { + return new FunctionValue(args -> { + Arguments.check(1, args.length); + f.apply(args[0].asString()); + return NumberValue.ZERO; + }); + } + + public static Number getNumber(Value value) { + if (value.type() == Types.NUMBER) return ((NumberValue) value).raw(); + return value.asInt(); + } +} diff --git a/src/main/java/com/annimon/ownlang/lib/modules/forms.java b/src/main/java/com/annimon/ownlang/lib/modules/forms.java new file mode 100644 index 0000000..04e4a98 --- /dev/null +++ b/src/main/java/com/annimon/ownlang/lib/modules/forms.java @@ -0,0 +1,91 @@ +package com.annimon.ownlang.lib.modules; + +import com.annimon.ownlang.annotations.ConstantInitializer; +import com.annimon.ownlang.lib.*; +import com.annimon.ownlang.lib.modules.functions.forms.Components; +import com.annimon.ownlang.lib.modules.functions.forms.LayoutManagers; +import java.awt.BorderLayout; +import javax.swing.BoxLayout; +import javax.swing.JFrame; +import javax.swing.SwingConstants; + +/** + * + * @author aNNiMON + */ +@ConstantInitializer +public final class forms implements Module { + + public static void initConstants() { + // JFrame constants + Variables.define("DISPOSE_ON_CLOSE", NumberValue.of(JFrame.DISPOSE_ON_CLOSE)); + Variables.define("DO_NOTHING_ON_CLOSE", NumberValue.of(JFrame.DO_NOTHING_ON_CLOSE)); + Variables.define("EXIT_ON_CLOSE", NumberValue.of(JFrame.EXIT_ON_CLOSE)); + Variables.define("HIDE_ON_CLOSE", NumberValue.of(JFrame.HIDE_ON_CLOSE)); + + // SwinfConstants + final MapValue swing = new MapValue(20); + swing.set(new StringValue("BOTTOM"), NumberValue.of(SwingConstants.BOTTOM)); + swing.set(new StringValue("CENTER"), NumberValue.of(SwingConstants.CENTER)); + swing.set(new StringValue("EAST"), NumberValue.of(SwingConstants.EAST)); + swing.set(new StringValue("HORIZONTAL"), NumberValue.of(SwingConstants.HORIZONTAL)); + swing.set(new StringValue("LEADING"), NumberValue.of(SwingConstants.LEADING)); + swing.set(new StringValue("LEFT"), NumberValue.of(SwingConstants.LEFT)); + swing.set(new StringValue("NEXT"), NumberValue.of(SwingConstants.NEXT)); + swing.set(new StringValue("NORTH"), NumberValue.of(SwingConstants.NORTH)); + swing.set(new StringValue("NORTH_EAST"), NumberValue.of(SwingConstants.NORTH_EAST)); + swing.set(new StringValue("NORTH_WEST"), NumberValue.of(SwingConstants.NORTH_WEST)); + swing.set(new StringValue("PREVIOUS"), NumberValue.of(SwingConstants.PREVIOUS)); + swing.set(new StringValue("RIGHT"), NumberValue.of(SwingConstants.RIGHT)); + swing.set(new StringValue("SOUTH"), NumberValue.of(SwingConstants.SOUTH)); + swing.set(new StringValue("SOUTH_EAST"), NumberValue.of(SwingConstants.SOUTH_EAST)); + swing.set(new StringValue("SOUTH_WEST"), NumberValue.of(SwingConstants.SOUTH_WEST)); + swing.set(new StringValue("TOP"), NumberValue.of(SwingConstants.TOP)); + swing.set(new StringValue("TRAILING"), NumberValue.of(SwingConstants.TRAILING)); + swing.set(new StringValue("VERTICAL"), NumberValue.of(SwingConstants.VERTICAL)); + swing.set(new StringValue("WEST"), NumberValue.of(SwingConstants.WEST)); + Variables.define("SwingConstants", swing); + + // LayoutManagers constants + final MapValue border = new MapValue(13); + border.set(new StringValue("AFTER_LAST_LINE"), new StringValue(BorderLayout.AFTER_LAST_LINE)); + border.set(new StringValue("AFTER_LINE_ENDS"), new StringValue(BorderLayout.AFTER_LINE_ENDS)); + border.set(new StringValue("BEFORE_FIRST_LINE"), new StringValue(BorderLayout.BEFORE_FIRST_LINE)); + border.set(new StringValue("BEFORE_LINE_BEGINS"), new StringValue(BorderLayout.BEFORE_LINE_BEGINS)); + border.set(new StringValue("CENTER"), new StringValue(BorderLayout.CENTER)); + border.set(new StringValue("EAST"), new StringValue(BorderLayout.EAST)); + border.set(new StringValue("LINE_END"), new StringValue(BorderLayout.LINE_END)); + border.set(new StringValue("LINE_START"), new StringValue(BorderLayout.LINE_START)); + border.set(new StringValue("NORTH"), new StringValue(BorderLayout.NORTH)); + border.set(new StringValue("PAGE_END"), new StringValue(BorderLayout.PAGE_END)); + border.set(new StringValue("PAGE_START"), new StringValue(BorderLayout.PAGE_START)); + border.set(new StringValue("SOUTH"), new StringValue(BorderLayout.SOUTH)); + border.set(new StringValue("WEST"), new StringValue(BorderLayout.WEST)); + Variables.define("BorderLayout", border); + + final MapValue box = new MapValue(4); + box.set(new StringValue("LINE_AXIS"), NumberValue.of(BoxLayout.LINE_AXIS)); + box.set(new StringValue("PAGE_AXIS"), NumberValue.of(BoxLayout.PAGE_AXIS)); + box.set(new StringValue("X_AXIS"), NumberValue.of(BoxLayout.X_AXIS)); + box.set(new StringValue("Y_AXIS"), NumberValue.of(BoxLayout.Y_AXIS)); + Variables.define("BoxLayout", box); + } + + @Override + public void init() { + initConstants(); + // Components + Functions.set("newButton", Components::newButton); + Functions.set("newLabel", Components::newLabel); + Functions.set("newPanel", Components::newPanel); + Functions.set("newTextField", Components::newTextField); + Functions.set("newWindow", Components::newWindow); + + // LayoutManagers + Functions.set("borderLayout", LayoutManagers::borderLayout); + Functions.set("boxLayout", LayoutManagers::boxLayout); + Functions.set("cardLayout", LayoutManagers::cardLayout); + Functions.set("gridLayout", LayoutManagers::gridLayout); + Functions.set("flowLayout", LayoutManagers::flowLayout); + } +} diff --git a/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/ComponentValue.java b/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/ComponentValue.java new file mode 100644 index 0000000..66f5833 --- /dev/null +++ b/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/ComponentValue.java @@ -0,0 +1,162 @@ +package com.annimon.ownlang.lib.modules.functions.forms; + +import com.annimon.ownlang.exceptions.TypeException; +import com.annimon.ownlang.lib.Arguments; +import com.annimon.ownlang.lib.ArrayValue; +import static com.annimon.ownlang.lib.Converters.*; +import com.annimon.ownlang.lib.Function; +import com.annimon.ownlang.lib.FunctionValue; +import com.annimon.ownlang.lib.MapValue; +import com.annimon.ownlang.lib.NumberValue; +import com.annimon.ownlang.lib.StringValue; +import com.annimon.ownlang.lib.Types; +import com.annimon.ownlang.lib.Value; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.util.function.Consumer; +import java.util.function.Supplier; + +public abstract class ComponentValue extends MapValue { + + final Component component; + + public ComponentValue(int functionsCount, Component component) { + super(functionsCount + 42); + this.component = component; + init(); + } + + private void init() { + set(new StringValue("onKeyAction"), new FunctionValue(this::addKeyListener)); + set(new StringValue("addKeyListener"), new FunctionValue(this::addKeyListener)); + set(new StringValue("getFocusTraversalKeysEnabled"), voidToBoolean(component::getFocusTraversalKeysEnabled)); + set(new StringValue("getHeight"), voidToInt(component::getHeight)); + set(new StringValue("getIgnoreRepaint"), voidToBoolean(component::getIgnoreRepaint)); + set(new StringValue("getLocation"), new FunctionValue(this::getLocation)); + set(new StringValue("getLocationOnScreen"), new FunctionValue(this::getLocationOnScreen)); + set(new StringValue("getMinimumSize"), dimensionFunction(component::getMinimumSize)); + set(new StringValue("getMaximumSize"), dimensionFunction(component::getMaximumSize)); + set(new StringValue("getName"), voidToString(component::getName)); + set(new StringValue("getPreferredSize"), dimensionFunction(component::getPreferredSize)); + set(new StringValue("getSize"), dimensionFunction(component::getSize)); + set(new StringValue("getWidth"), voidToInt(component::getWidth)); + set(new StringValue("getX"), voidToInt(component::getX)); + set(new StringValue("getY"), voidToInt(component::getY)); + set(new StringValue("hasFocus"), voidToBoolean(component::hasFocus)); + set(new StringValue("invalidate"), voidToVoid(component::invalidate)); + + set(new StringValue("isDisplayable"), voidToBoolean(component::isDisplayable)); + set(new StringValue("isDoubleBuffered"), voidToBoolean(component::isDoubleBuffered)); + set(new StringValue("isEnabled"), voidToBoolean(component::isEnabled)); + set(new StringValue("isFocusOwner"), voidToBoolean(component::isFocusOwner)); + set(new StringValue("isFocusable"), voidToBoolean(component::isFocusable)); + set(new StringValue("isLightweight"), voidToBoolean(component::isLightweight)); + set(new StringValue("isOpaque"), voidToBoolean(component::isOpaque)); + set(new StringValue("isShowing"), voidToBoolean(component::isShowing)); + set(new StringValue("isValid"), voidToBoolean(component::isValid)); + set(new StringValue("isVisible"), voidToBoolean(component::isVisible)); + + set(new StringValue("requestFocus"), voidToVoid(component::requestFocus)); + set(new StringValue("requestFocusInWindow"), voidToBoolean(component::requestFocusInWindow)); + set(new StringValue("repaint"), voidToVoid(component::repaint)); + set(new StringValue("revalidate"), voidToVoid(component::revalidate)); + set(new StringValue("setMaximumSize"), voidDimensionFunction(component::setMaximumSize)); + set(new StringValue("setMinimumSize"), voidDimensionFunction(component::setMinimumSize)); + set(new StringValue("setName"), stringToVoid(component::setName)); + set(new StringValue("setPreferredSize"), voidDimensionFunction(component::setPreferredSize)); + set(new StringValue("setSize"), voidDimensionFunction(component::setSize)); + set(new StringValue("setVisible"), booleanOptToVoid(component::setVisible)); + set(new StringValue("setLocation"), new FunctionValue(this::setLocation)); + set(new StringValue("validate"), voidToVoid(component::validate)); + } + + private Value addKeyListener(Value... args) { + Arguments.check(1, args.length); + final int type = args[0].type(); + if (type != Types.FUNCTION) { + throw new TypeException("Function expected, but found " + Types.typeToString(type)); + } + final Function action = ((FunctionValue) args[0]).getValue(); + component.addKeyListener(new KeyListener() { + + @Override + public void keyTyped(KeyEvent e) { + handleKeyEvent("typed", e); + } + + @Override + public void keyPressed(KeyEvent e) { + handleKeyEvent("pressed", e); + } + + @Override + public void keyReleased(KeyEvent e) { + handleKeyEvent("released", e); + } + + private void handleKeyEvent(String type, final KeyEvent e) { + final MapValue map = new MapValue(15); + map.set(new StringValue("extendedKeyCode"), NumberValue.of(e.getExtendedKeyCode())); + map.set(new StringValue("keyChar"), NumberValue.of(e.getKeyChar())); + map.set(new StringValue("keyCode"), NumberValue.of(e.getKeyCode())); + map.set(new StringValue("keyLocation"), NumberValue.of(e.getKeyLocation())); + map.set(new StringValue("id"), NumberValue.of(e.getID())); + map.set(new StringValue("isActionKey"), NumberValue.fromBoolean(e.isActionKey())); + map.set(new StringValue("isAltDown"), NumberValue.fromBoolean(e.isAltDown())); + map.set(new StringValue("isAltGraphDown"), NumberValue.fromBoolean(e.isAltGraphDown())); + map.set(new StringValue("isConsumed"), NumberValue.fromBoolean(e.isConsumed())); + map.set(new StringValue("isControlDown"), NumberValue.fromBoolean(e.isControlDown())); + map.set(new StringValue("isMetaDown"), NumberValue.fromBoolean(e.isMetaDown())); + map.set(new StringValue("isShiftDown"), NumberValue.fromBoolean(e.isShiftDown())); + map.set(new StringValue("modifiers"), NumberValue.of(e.getModifiers())); + action.execute(new StringValue(type), map); + } + }); + return NumberValue.ZERO; + } + + private Value getLocation(Value... args) { + final Point location = component.getLocation(); + final ArrayValue result = new ArrayValue(2); + result.set(0, NumberValue.of(location.x)); + result.set(1, NumberValue.of(location.y)); + return result; + } + + private Value getLocationOnScreen(Value... args) { + final Point location = component.getLocationOnScreen(); + final ArrayValue result = new ArrayValue(2); + result.set(0, NumberValue.of(location.x)); + result.set(1, NumberValue.of(location.y)); + return result; + } + + private Value setLocation(Value... args) { + Arguments.check(2, args.length); + component.setLocation(args[0].asInt(), args[1].asInt()); + return NumberValue.ZERO; + } + + + + protected static FunctionValue dimensionFunction(Supplier s) { + return new FunctionValue(args -> { + final Dimension dimension = s.get(); + final ArrayValue result = new ArrayValue(2); + result.set(0, NumberValue.of(dimension.getWidth())); + result.set(1, NumberValue.of(dimension.getHeight())); + return result; + }); + } + + protected static FunctionValue voidDimensionFunction(Consumer s) { + return new FunctionValue(args -> { + Arguments.check(2, args.length); + s.accept(new Dimension(args[0].asInt(), args[1].asInt())); + return NumberValue.ZERO; + }); + } +} \ No newline at end of file diff --git a/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/Components.java b/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/Components.java new file mode 100644 index 0000000..6639af9 --- /dev/null +++ b/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/Components.java @@ -0,0 +1,52 @@ +package com.annimon.ownlang.lib.modules.functions.forms; + +import com.annimon.ownlang.lib.Arguments; +import com.annimon.ownlang.lib.Value; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.SwingConstants; + +/** + * Functions for working with components. + */ +public final class Components { + + public static Value newWindow(Value... args) { + Arguments.checkOrOr(0, 1, args.length); + String title = (args.length == 1) ? args[0].asString() : ""; + final JFrame frame = new JFrame(title); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + return new JFrameValue(frame); + } + + public static Value newPanel(Value... args) { + Arguments.checkOrOr(0, 1, args.length); + final JPanel panel = new JPanel(); + if (args.length == 1) { + panel.setLayout( ((LayoutManagerValue) args[0]).layout ); + } + return new JPanelValue(panel); + } + + public static Value newButton(Value... args) { + Arguments.checkOrOr(0, 1, args.length); + String text = (args.length == 1) ? args[0].asString() : ""; + return new JButtonValue(new JButton(text)); + } + + public static Value newLabel(Value... args) { + Arguments.checkRange(0, 2, args.length); + String text = (args.length >= 1) ? args[0].asString() : ""; + int align = (args.length == 2) ? args[0].asInt() : SwingConstants.LEADING; + return new JLabelValue(new JLabel(text, align)); + } + + public static Value newTextField(Value... args) { + Arguments.checkOrOr(0, 1, args.length); + String text = (args.length == 1) ? args[0].asString() : ""; + return new JTextFieldValue(new JTextField(text)); + } +} diff --git a/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/ContainerValue.java b/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/ContainerValue.java new file mode 100644 index 0000000..7fc3b36 --- /dev/null +++ b/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/ContainerValue.java @@ -0,0 +1,81 @@ +package com.annimon.ownlang.lib.modules.functions.forms; + +import com.annimon.ownlang.lib.Arguments; +import static com.annimon.ownlang.lib.Converters.*; +import com.annimon.ownlang.lib.FunctionValue; +import com.annimon.ownlang.lib.NumberValue; +import com.annimon.ownlang.lib.StringValue; +import com.annimon.ownlang.lib.Types; +import com.annimon.ownlang.lib.Value; +import java.awt.Component; +import java.awt.Container; +import javax.swing.JLabel; + +public abstract class ContainerValue extends ComponentValue { + + final Container container; + + public ContainerValue(int functionsCount, Container container) { + super(functionsCount + 10, container); + this.container = container; + init(); + } + + private void init() { + set(new StringValue("add"), new FunctionValue(this::add)); + set(new StringValue("remove"), new FunctionValue(this::remove)); + set(new StringValue("removeAll"), voidToVoid(container::removeAll)); + set(new StringValue("getAlignmentX"), voidToFloat(container::getAlignmentX)); + set(new StringValue("getAlignmentY"), voidToFloat(container::getAlignmentY)); + set(new StringValue("getComponentCount"), voidToInt(container::getComponentCount)); + set(new StringValue("isFocusCycleRoot"), voidToBoolean(container::isFocusCycleRoot)); + set(new StringValue("isValidateRoot"), voidToBoolean(container::isValidateRoot)); + set(new StringValue("setLayout"), new FunctionValue(this::setLayout)); + } + + private Value add(Value... args) { + Arguments.checkRange(1, 3, args.length); + + final Component newComponent; + if (args[0] instanceof ComponentValue) { + newComponent = ((ComponentValue) args[0]).component; + } else { + newComponent = new JLabel(args[0].asString()); + } + switch (args.length) { + case 1: + container.add(newComponent); + break; + case 2: + if (args[1].type() == Types.NUMBER) { + // add(component, index) + container.add(newComponent, args[1].asInt()); + } else { + // add(component, constraints) + container.add(newComponent, args[1].raw()); + } + break; + case 3: + // add(component, constraints, index) + container.add(newComponent, args[1].raw(), args[2].asInt()); + break; + } + return NumberValue.ZERO; + } + + private Value remove(Value... args) { + Arguments.check(1, args.length); + if (args[0] instanceof JComponentValue) { + container.remove(((JComponentValue) args[0]).component); + } else { + container.remove(args[0].asInt()); + } + return NumberValue.ZERO; + } + + private Value setLayout(Value... args) { + Arguments.check(1, args.length); + container.setLayout(((LayoutManagerValue) args[0]).layout); + return NumberValue.ZERO; + } +} \ No newline at end of file diff --git a/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/JButtonValue.java b/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/JButtonValue.java new file mode 100644 index 0000000..0e00c40 --- /dev/null +++ b/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/JButtonValue.java @@ -0,0 +1,38 @@ +package com.annimon.ownlang.lib.modules.functions.forms; + +import com.annimon.ownlang.exceptions.TypeException; +import com.annimon.ownlang.lib.Arguments; +import com.annimon.ownlang.lib.Function; +import com.annimon.ownlang.lib.FunctionValue; +import com.annimon.ownlang.lib.NumberValue; +import com.annimon.ownlang.lib.StringValue; +import com.annimon.ownlang.lib.Types; +import com.annimon.ownlang.lib.Value; +import javax.swing.JButton; + +public class JButtonValue extends JComponentValue { + + final JButton button; + + public JButtonValue(JButton button) { + super(2, button); + this.button = button; + init(); + } + + private void init() { + set(new StringValue("onClick"), new FunctionValue(this::addActionListener)); + set(new StringValue("addActionListener"), new FunctionValue(this::addActionListener)); + } + + private Value addActionListener(Value... args) { + Arguments.check(1, args.length); + final int type = args[0].type(); + if (type != Types.FUNCTION) { + throw new TypeException("Function expected, but found " + Types.typeToString(type)); + } + final Function action = ((FunctionValue) args[0]).getValue(); + button.addActionListener(e -> action.execute()); + return NumberValue.ZERO; + } +} \ No newline at end of file diff --git a/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/JComponentValue.java b/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/JComponentValue.java new file mode 100644 index 0000000..eb5e67e --- /dev/null +++ b/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/JComponentValue.java @@ -0,0 +1,21 @@ +package com.annimon.ownlang.lib.modules.functions.forms; + +import static com.annimon.ownlang.lib.Converters.*; +import com.annimon.ownlang.lib.StringValue; +import javax.swing.JComponent; + +public abstract class JComponentValue extends ContainerValue { + + final JComponent jComponent; + + public JComponentValue(int functionsCount, JComponent jComponent) { + super(functionsCount + 2, jComponent); + this.jComponent = jComponent; + init(); + } + + private void init() { + set(new StringValue("getToolTipText"), voidToString(jComponent::getToolTipText)); + set(new StringValue("setToolTipText"), stringToVoid(jComponent::setToolTipText)); + } +} diff --git a/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/JFrameValue.java b/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/JFrameValue.java new file mode 100644 index 0000000..c41a2cf --- /dev/null +++ b/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/JFrameValue.java @@ -0,0 +1,28 @@ +package com.annimon.ownlang.lib.modules.functions.forms; + +import static com.annimon.ownlang.lib.Converters.*; +import com.annimon.ownlang.lib.StringValue; +import javax.swing.JFrame; + +public class JFrameValue extends ContainerValue { + + final JFrame frame; + + public JFrameValue(JFrame frame) { + super(9, frame); + this.frame = frame; + init(); + } + + private void init() { + set(new StringValue("dispose"), voidToVoid(frame::dispose)); + set(new StringValue("getTitle"), voidToString(frame::getTitle)); + set(new StringValue("getDefaultCloseOperation"), voidToInt(frame::getDefaultCloseOperation)); + set(new StringValue("pack"), voidToVoid(frame::pack)); + set(new StringValue("setAlwaysOnTop"), booleanOptToVoid(frame::setAlwaysOnTop)); + set(new StringValue("setDefaultCloseOperation"), intToVoid(frame::setDefaultCloseOperation)); + set(new StringValue("setLocationByPlatform"), booleanOptToVoid(frame::setLocationByPlatform)); + set(new StringValue("setResizable"), booleanOptToVoid(frame::setResizable)); + set(new StringValue("setTitle"), stringToVoid(frame::setTitle)); + } +} \ No newline at end of file diff --git a/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/JLabelValue.java b/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/JLabelValue.java new file mode 100644 index 0000000..e7a2904 --- /dev/null +++ b/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/JLabelValue.java @@ -0,0 +1,36 @@ +package com.annimon.ownlang.lib.modules.functions.forms; + +import static com.annimon.ownlang.lib.Converters.*; +import com.annimon.ownlang.lib.StringValue; +import javax.swing.JLabel; + +public class JLabelValue extends JComponentValue { + + final JLabel label; + + public JLabelValue(JLabel label) { + super(17, label); + this.label = label; + init(); + } + + private void init() { + set(new StringValue("getDisplayedMnemonic"), voidToInt(label::getDisplayedMnemonic)); + set(new StringValue("getDisplayedMnemonicIndex"), voidToInt(label::getDisplayedMnemonicIndex)); + set(new StringValue("getHorizontalAlignment"), voidToInt(label::getHorizontalAlignment)); + set(new StringValue("getHorizontalTextPosition"), voidToInt(label::getHorizontalTextPosition)); + set(new StringValue("getIconTextGap"), voidToInt(label::getIconTextGap)); + set(new StringValue("getVerticalAlignment"), voidToInt(label::getVerticalAlignment)); + set(new StringValue("getVerticalTextPosition"), voidToInt(label::getVerticalTextPosition)); + + set(new StringValue("getText"), voidToString(label::getText)); + set(new StringValue("setDisplayedMnemonic"), intToVoid(label::setDisplayedMnemonic)); + set(new StringValue("setDisplayedMnemonicIndex"), intToVoid(label::setDisplayedMnemonicIndex)); + set(new StringValue("setHorizontalAlignment"), intToVoid(label::setHorizontalAlignment)); + set(new StringValue("setHorizontalTextPosition"), intToVoid(label::setHorizontalTextPosition)); + set(new StringValue("setIconTextGap"), intToVoid(label::setIconTextGap)); + set(new StringValue("setVerticalAlignment"), intToVoid(label::setVerticalAlignment)); + set(new StringValue("setVerticalTextPosition"), intToVoid(label::setVerticalTextPosition)); + set(new StringValue("setText"), stringToVoid(label::setText)); + } +} \ No newline at end of file diff --git a/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/JPanelValue.java b/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/JPanelValue.java new file mode 100644 index 0000000..7e6ad92 --- /dev/null +++ b/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/JPanelValue.java @@ -0,0 +1,17 @@ +package com.annimon.ownlang.lib.modules.functions.forms; + +import javax.swing.JPanel; + +public class JPanelValue extends JComponentValue { + + final JPanel panel; + + public JPanelValue(JPanel panel) { + super(0, panel); + this.panel = panel; + init(); + } + + private void init() { + } +} \ No newline at end of file diff --git a/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/JTextFieldValue.java b/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/JTextFieldValue.java new file mode 100644 index 0000000..8147a26 --- /dev/null +++ b/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/JTextFieldValue.java @@ -0,0 +1,53 @@ +package com.annimon.ownlang.lib.modules.functions.forms; + +import com.annimon.ownlang.exceptions.TypeException; +import com.annimon.ownlang.lib.Arguments; +import static com.annimon.ownlang.lib.Converters.*; +import com.annimon.ownlang.lib.Function; +import com.annimon.ownlang.lib.FunctionValue; +import com.annimon.ownlang.lib.NumberValue; +import com.annimon.ownlang.lib.StringValue; +import com.annimon.ownlang.lib.Types; +import com.annimon.ownlang.lib.Value; +import javax.swing.JTextField; + +public class JTextFieldValue extends JComponentValue { + + private final JTextField textField; + + public JTextFieldValue(JTextField textField) { + super(16, textField); + this.textField = textField; + init(); + } + + private void init() { + set(new StringValue("onAction"), new FunctionValue(this::addActionListener)); + set(new StringValue("addActionListener"), new FunctionValue(this::addActionListener)); + set(new StringValue("getCaretPosition"), voidToInt(textField::getCaretPosition)); + set(new StringValue("getColumns"), voidToInt(textField::getColumns)); + set(new StringValue("getHorizontalAlignment"), voidToInt(textField::getHorizontalAlignment)); + set(new StringValue("getSelectionEnd"), voidToInt(textField::getSelectionEnd)); + set(new StringValue("getSelectionStart"), voidToInt(textField::getSelectionStart)); + set(new StringValue("getScrollOffset"), voidToInt(textField::getScrollOffset)); + set(new StringValue("getText"), voidToString(textField::getText)); + set(new StringValue("setCaretPosition"), intToVoid(textField::setCaretPosition)); + set(new StringValue("setColumns"), intToVoid(textField::setColumns)); + set(new StringValue("setHorizontalAlignment"), intToVoid(textField::setHorizontalAlignment)); + set(new StringValue("setScrollOffset"), intToVoid(textField::setScrollOffset)); + set(new StringValue("setSelectionEnd"), intToVoid(textField::setSelectionEnd)); + set(new StringValue("setSelectionStart"), intToVoid(textField::setSelectionStart)); + set(new StringValue("setText"), stringToVoid(textField::setText)); + } + + private Value addActionListener(Value... args) { + Arguments.check(1, args.length); + final int type = args[0].type(); + if (type != Types.FUNCTION) { + throw new TypeException("Function expected, but found " + Types.typeToString(type)); + } + final Function action = ((FunctionValue) args[0]).getValue(); + textField.addActionListener(e -> action.execute()); + return NumberValue.ZERO; + } +} \ No newline at end of file diff --git a/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/LayoutManagerValue.java b/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/LayoutManagerValue.java new file mode 100644 index 0000000..3ed2c42 --- /dev/null +++ b/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/LayoutManagerValue.java @@ -0,0 +1,14 @@ +package com.annimon.ownlang.lib.modules.functions.forms; + +import com.annimon.ownlang.lib.MapValue; +import java.awt.LayoutManager; + +public class LayoutManagerValue extends MapValue { + + final LayoutManager layout; + + public LayoutManagerValue(LayoutManager layout) { + super(0); + this.layout = layout; + } +} \ No newline at end of file diff --git a/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/LayoutManagers.java b/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/LayoutManagers.java new file mode 100644 index 0000000..0791d28 --- /dev/null +++ b/src/main/java/com/annimon/ownlang/lib/modules/functions/forms/LayoutManagers.java @@ -0,0 +1,100 @@ +package com.annimon.ownlang.lib.modules.functions.forms; + +import com.annimon.ownlang.lib.Arguments; +import com.annimon.ownlang.lib.Value; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.FlowLayout; +import java.awt.GridLayout; +import javax.swing.BoxLayout; + +/** + * Functions for working with layout managers. + */ +public final class LayoutManagers { + + public static Value borderLayout(Value... args) { + Arguments.checkOrOr(0, 2, args.length); + int hgap = (args.length == 2) ? args[0].asInt() : 0; + int vgap = (args.length == 2) ? args[1].asInt() : 0; + return new LayoutManagerValue( + new BorderLayout(hgap, vgap) + ); + } + + public static Value boxLayout(Value... args) { + Arguments.checkOrOr(1, 2, args.length); + int axis = (args.length == 2) ? args[1].asInt() : BoxLayout.PAGE_AXIS; + return new LayoutManagerValue( + new BoxLayout(((JPanelValue) args[0]).panel, axis) + ); + } + + public static Value cardLayout(Value... args) { + Arguments.checkOrOr(0, 2, args.length); + int hgap = (args.length == 2) ? args[0].asInt() : 0; + int vgap = (args.length == 2) ? args[1].asInt() : 0; + return new LayoutManagerValue( + new CardLayout(hgap, vgap) + ); + } + + public static Value gridLayout(Value... args) { + Arguments.checkRange(0, 4, args.length); + int rows = 1, cols = 0, hgap = 0, vgap = 0; + switch (args.length) { + case 1: + rows = args[0].asInt(); + break; + case 2: + rows = args[0].asInt(); + cols = args[1].asInt(); + break; + case 3: + rows = args[0].asInt(); + cols = args[1].asInt(); + hgap = args[2].asInt(); + break; + case 4: + rows = args[0].asInt(); + cols = args[1].asInt(); + hgap = args[2].asInt(); + vgap = args[3].asInt(); + break; + } + return new LayoutManagerValue( + new GridLayout(rows, cols, hgap, vgap) + ); + } + + public static Value flowLayout(Value... args) { + Arguments.checkRange(0, 3, args.length); + final int align, hgap, vgap; + switch (args.length) { + case 1: + align = args[0].asInt(); + hgap = 5; + vgap = 5; + break; + case 2: + align = FlowLayout.CENTER; + hgap = args[0].asInt(); + vgap = args[1].asInt(); + break; + case 3: + align = args[0].asInt(); + hgap = args[1].asInt(); + vgap = args[2].asInt(); + break; + default: + align = FlowLayout.CENTER; + hgap = 5; + vgap = 5; + break; + } + + return new LayoutManagerValue( + new FlowLayout(align, hgap, vgap) + ); + } +}