-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathScriptTest.java
More file actions
122 lines (111 loc) · 4.47 KB
/
ScriptTest.java
File metadata and controls
122 lines (111 loc) · 4.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package script;
import java.awt.*;
import java.beans.*;
import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import javax.script.*;
import javax.swing.*;
/**
* @version 1.02 2016-05-10
* @author Cay Horstmann
*/
public class ScriptTest
{
public static void main(String[] args)
{
EventQueue.invokeLater(() ->
{
try
{
ScriptEngineManager manager = new ScriptEngineManager();
String language;
if (args.length == 0)
{
System.out.println("Available factories: ");
for (ScriptEngineFactory factory : manager.getEngineFactories())
System.out.println(factory.getEngineName());
language = "nashorn";
}
else language = args[0];
final ScriptEngine engine = manager.getEngineByName(language);
if (engine == null)
{
System.err.println("No engine for " + language);
System.exit(1);
}
final String frameClassName = args.length < 2 ? "buttons1.ButtonFrame" : args[1];
JFrame frame = (JFrame) Class.forName(frameClassName).newInstance();
InputStream in = frame.getClass().getResourceAsStream("init." + language);
if (in != null) engine.eval(new InputStreamReader(in));
Map<String, Component> components = new HashMap<>();
getComponentBindings(frame, components);
components.forEach((name, c) -> engine.put(name, c));
final Properties events = new Properties();
in = frame.getClass().getResourceAsStream(language + ".properties");
events.load(in);
for (final Object e : events.keySet())
{
String[] s = ((String) e).split("\\.");
addListener(s[0], s[1], (String) events.get(e), engine, components);
}
frame.setTitle("ScriptTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
catch (ReflectiveOperationException | IOException
| ScriptException | IntrospectionException ex)
{
ex.printStackTrace();
}
});
}
/**
* Gathers all named components in a container.
* @param c the component
* @param namedComponents a map into which to enter the component names and components
*/
private static void getComponentBindings(Component c, Map<String, Component> namedComponents)
{
String name = c.getName();
if (name != null) { namedComponents.put(name, c); }
if (c instanceof Container)
{
for (Component child : ((Container) c).getComponents())
getComponentBindings(child, namedComponents);
}
}
/**
* Adds a listener to an object whose listener method executes a script.
* @param beanName the name of the bean to which the listener should be added
* @param eventName the name of the listener type, such as "action" or "change"
* @param scriptCode the script code to be executed
* @param engine the engine that executes the code
* @param bindings the bindings for the execution
* @throws IntrospectionException
*/
private static void addListener(String beanName, String eventName, final String scriptCode,
final ScriptEngine engine, Map<String, Component> components)
throws ReflectiveOperationException, IntrospectionException
{
Object bean = components.get(beanName);
EventSetDescriptor descriptor = getEventSetDescriptor(bean, eventName);
if (descriptor == null) return;
descriptor.getAddListenerMethod().invoke(bean,
Proxy.newProxyInstance(null, new Class[] { descriptor.getListenerType() },
(proxy, method, args) ->
{
engine.eval(scriptCode);
return null;
}
));
}
private static EventSetDescriptor getEventSetDescriptor(Object bean, String eventName)
throws IntrospectionException
{
for (EventSetDescriptor descriptor : Introspector.getBeanInfo(bean.getClass())
.getEventSetDescriptors())
if (descriptor.getName().equals(eventName)) return descriptor;
return null;
}
}