Reflection with my UI library

In my UI library, all javascript actions are parsed and values from other components can be retrieved with a syntax like:
[icode]$[getLayer(2).getText()][/icode] which would get the component on layer 2 and (since it’s an EditField component), would get the text for it

Here is how I call the method via reflection:

Matcher matcher = Pattern.compile("\\$\\[(.*?)\\]").matcher(string); //  format $[getLayer(3).getValue()]
		while (matcher.find()) {
			String match = matcher.group();
			String nmatch = match.substring(2, match.length() - 1);
			String[] methodData = nmatch.split("\\.");
			int layer = Integer.parseInt(methodData[0].substring(9, methodData[0].length() - 1));
			String fullMethod = methodData[1];
			String[] fullMethodData = fullMethod.split("\\(");
			String method = fullMethodData[0];
//			String args = fullMethodData[1].substring(0, fullMethodData[1].length() - 1);
			Component component = ui.getLayer(layer);
			String value = "";
			try {
				Method reflectedMethod = component.getClass().getDeclaredMethod(method, null);
				reflectedMethod.setAccessible(true);
				value = String.valueOf(reflectedMethod.invoke(component)); // method is called, but returns a blank string
				System.out.println("'" + value + "'"); // just debug
			} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
				e.printStackTrace();
			}
			System.out.println(match + " --> " + value); // just debug
			string = string.replace(match, value);
		}
		return string;

Any help would be appreciated :slight_smile:

CopyableCougar4

[quote=""]
Try Nashorn? (If you really are set on using JS)

I’m using Nashorn, I just wanted to be able to write placeholders filled with component values at runtime.

CopyableCougar4

I can’t see why reflection or regex’s are needed here though.


var text = component.getLayer(2).getText()

If you’re already using JS, why wouldn’t you leverage it?
Dynamic stuff is rarely clean in Java.

I guess I’m confused as to why you need to do it on the Java side.

I needed the non-static UI object to be used to get the component to get the method from.

If there is a JavaScript solution with Nashorn that would make my day :slight_smile:

CopyableCougar4

Seems nasty, but… Singleton?

import javax.script.*;
import javax.swing.JComponent;
import javax.swing.JPanel;

public class NashornTest {
	
	private static JPanel comp = new JPanel();
	
	public static JComponent instance() {
		return comp;
	}
	
	public static void main(String[] a) throws ScriptException {
		ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
		
		String script = "print(Java.type('NashornTest').instance().getSize());";
		
		engine.eval(script);
	}
}

I don’t actually know enough about JS/Nashorn to come up with a better solution.

EDIT: could use one of the (IMO) legit uses of regexes for ergonomics:


// use $ in your script to reference the singleton:
script = script.replaceAll(Pattern.quote("$"), "Java.type(...).instance()");
engine.eval(script);
...

Umm… I guess it works now :slight_smile: I just restarted eclipse and it works fine now…

If I start to have issues with working slowly, I will try faster solutions but reflection seems to work for now :slight_smile:

CopyableCougar4