source: trunk/src/org/expeditee/items/widgets/JSWidget.java@ 963

Last change on this file since 963 was 919, checked in by jts21, 10 years ago

Added license headers to all files, added full GPL3 license file, moved license header generator script to dev/bin/scripts

File size: 5.5 KB
Line 
1/**
2 * JSWidget.java
3 * Copyright (C) 2010 New Zealand Digital Library, http://expeditee.org
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19package org.expeditee.items.widgets;
20
21import java.awt.BorderLayout;
22import java.awt.Component;
23import java.awt.Graphics2D;
24import java.util.LinkedList;
25import java.util.List;
26
27import javax.script.Invocable;
28import javax.script.ScriptEngine;
29import javax.swing.JPanel;
30
31import org.expeditee.actions.Javascript2;
32import org.expeditee.gui.DisplayIO;
33import org.expeditee.items.ItemParentStateChangedEvent;
34import org.expeditee.items.JSThreadable;
35import org.expeditee.items.Text;
36
37/**
38 * Class for extending Expeditee with widgets coded in Javascript
39 *
40 * @author jts21
41 *
42 */
43public class JSWidget extends DataFrameWidget implements JSThreadable {
44
45 private static final Object global = Javascript2.eval("new Object()");
46
47 // a method to run that will set up and return the root JComponent for this Widget
48 private final String init;
49 // a method to run to populate a List<String> with our state
50 private final String save;
51 // a method to run that will load state from a String[]
52 private final String load;
53
54 // we have our own script context since it needs to have some global variables which are specific to each widget
55 private final ScriptEngine scriptEngine;
56 private final Invocable invocable;
57 // component created by running our constructor
58 private final Component component;
59 // container for our component
60 private final JPanel container;
61
62 private static Text getSauce() {
63 Text source = new Text(DisplayIO.getCurrentFrame().getNextItemID(), "@iw: org.expeditee.items.widgets.JSWidget");
64 source.setParent(DisplayIO.getCurrentFrame());
65 return source;
66 }
67
68 private JSWidget(Text source, int width, int height, String init, String save, String load) throws Exception {
69 super(source, new JPanel(new BorderLayout()), -1, width, -1, -1, height, -1);
70 this.init = init;
71 this.save = save;
72 this.load = load;
73 this.container = (JPanel) super._swingComponent;
74 this.scriptEngine = Javascript2.scriptEngineManager.getEngineByMimeType("application/javascript");
75 this.invocable = (Invocable) this.scriptEngine;
76 this.scriptEngine.put("global", global);
77 this.scriptEngine.put("invocable", this.invocable);
78 this.scriptEngine.put("widget", this);
79 this.scriptEngine.put("container", this.container);
80 System.out.println(this.init);
81 this.component = (Component) this.scriptEngine.eval("var init = " + this.init + "\ninit()");
82 this.container.add(component);
83 this.scriptEngine.put("component", this.component);
84 this.scriptEngine.eval("save = " + this.save);
85 this.scriptEngine.eval("load = " + this.load);
86 }
87
88 private JSWidget(Text source, String init, String save, String load) throws Exception {
89 this(source, 100, 100, init, save, load);
90 }
91
92 public JSWidget(Text source, String[] args) throws Exception {
93 this(source, source.getData().get(0).replaceAll("\\\\n", "\n"),
94 source.getData().get(1).replaceAll("\\\\n", "\n"),
95 source.getData().get(2).replaceAll("\\\\n", "\n"));
96 this.invocable.invokeFunction("load", (Object) args);
97 }
98
99 public JSWidget(int width, int height, String init, String save, String load) throws Exception {
100 this(getSauce(), width, height, init, save, load);
101 }
102
103 public JSWidget(String init, String save, String load) throws Exception {
104 this(100, 100, init, save, load);
105 }
106
107 @Override
108 protected List<String> getData() {
109 List<String> value = new LinkedList<String>();
110 value.add(this.init.replaceAll("[\n\r]", "\\\\n"));
111 value.add(this.save.replaceAll("[\n\r]", "\\\\n"));
112 value.add(this.load.replaceAll("[\n\r]", "\\\\n"));
113 return value;
114 }
115
116 @Override
117 protected String[] getArgs() {
118 try {
119 List<String> args = new LinkedList<String>();
120 this.invocable.invokeFunction("save", (Object)args);
121 return args.toArray(new String[0]);
122 } catch (Exception e) {
123 e.printStackTrace();
124 return null;
125 }
126 }
127
128 private List<JSThread> threads = new LinkedList<JSThread>();
129
130 public JSThread addThread(String code) {
131 JSThread t = new JSThread(scriptEngine, code);
132 this.threads.add(t);
133 return t;
134 }
135
136 @Override
137 public void onParentStateChanged(int e) {
138 switch (e) {
139 case ItemParentStateChangedEvent.EVENT_TYPE_REMOVED:
140 case ItemParentStateChangedEvent.EVENT_TYPE_REMOVED_VIA_OVERLAY:
141 case ItemParentStateChangedEvent.EVENT_TYPE_HIDDEN:
142 for(JSThread t : this.threads) {
143 t.kill();
144 }
145 break;
146
147 case ItemParentStateChangedEvent.EVENT_TYPE_ADDED:
148 case ItemParentStateChangedEvent.EVENT_TYPE_ADDED_VIA_OVERLAY:
149 case ItemParentStateChangedEvent.EVENT_TYPE_SHOWN:
150 case ItemParentStateChangedEvent.EVENT_TYPE_SHOWN_VIA_OVERLAY:
151 for(JSThread t : this.threads) {
152 t.resume();
153 }
154 break;
155 }
156 }
157
158 @Override
159 protected void paintLink(Graphics2D g) {
160 return;
161 }
162}
Note: See TracBrowser for help on using the repository browser.