samer@0
|
1 /*
|
samer@0
|
2 * JAppletShell.java
|
samer@0
|
3 *
|
samer@0
|
4 * Copyright (c) 2000, Samer Abdallah, King's College London.
|
samer@0
|
5 * All rights reserved.
|
samer@0
|
6 *
|
samer@0
|
7 * This software is provided AS iS and WITHOUT ANY WARRANTY;
|
samer@0
|
8 * without even the implied warranty of MERCHANTABILITY or
|
samer@0
|
9 * FITNESS FOR A PARTICULAR PURPOSE.
|
samer@0
|
10 */
|
samer@0
|
11
|
samer@0
|
12 package samer.applet;
|
samer@0
|
13
|
samer@0
|
14 import java.applet.*;
|
samer@0
|
15 import java.awt.*;
|
samer@0
|
16 import java.awt.event.*;
|
samer@0
|
17 import java.util.*;
|
samer@0
|
18 import java.net.*;
|
samer@0
|
19 import java.io.*;
|
samer@0
|
20
|
samer@0
|
21 import samer.core.*;
|
samer@0
|
22 import samer.core.util.heavy.*;
|
samer@0
|
23 import samer.core.util.shell.*;
|
samer@0
|
24 import samer.core.util.*;
|
samer@0
|
25 import samer.core.Shell.*;
|
samer@0
|
26
|
samer@0
|
27 import samer.core.util.heavy.Frame;
|
samer@0
|
28 import samer.core.util.heavy.Dialog;
|
samer@0
|
29 import samer.core.util.Properties;
|
samer@0
|
30 import samer.core.NumberViewer;
|
samer@0
|
31 import samer.core.viewers.*;
|
samer@0
|
32 import samer.core.types.*;
|
samer@0
|
33
|
samer@0
|
34 import samer.core.util.heavy.Console;
|
samer@0
|
35 import java.util.Hashtable;
|
samer@0
|
36
|
samer@0
|
37 /*
|
samer@0
|
38 To do:
|
samer@0
|
39 o 2 - Create optional output window
|
samer@0
|
40 3 - display commands in menu on Applet OR
|
samer@0
|
41 4 - commands on button bar in applet
|
samer@0
|
42
|
samer@0
|
43 6 - create Viewer to use Tools
|
samer@0
|
44 7 - manage agents
|
samer@0
|
45 8 - manage viewables
|
samer@0
|
46 */
|
samer@0
|
47
|
samer@0
|
48 /**
|
samer@0
|
49 This is a Shell that uses Applets to form a GUI. The basic idea is that
|
samer@0
|
50 each applet that gets created on a web page registers itself with shell
|
samer@0
|
51 as an available window, or perhaps as a special window like a console
|
samer@0
|
52 or viewables container. Then, whenever a script or something asks for
|
samer@0
|
53 a window, it gets to use one of the applets.
|
samer@0
|
54 */
|
samer@0
|
55
|
samer@0
|
56 public class JAppletShell implements Shell.Interface, Agent
|
samer@0
|
57 {
|
samer@0
|
58 static JAppletShell instance=null;
|
samer@0
|
59 private static Object mutex=new Object(); // to serialise Shell creation
|
samer@0
|
60
|
samer@0
|
61 private AgentManager am;
|
samer@0
|
62 private ViewableManager vm;
|
samer@0
|
63 private Properties props;
|
samer@0
|
64 private URL documentBase;
|
samer@0
|
65 private Container confr=null;
|
samer@0
|
66 private Console console=null;
|
samer@0
|
67 private ButtonBar buttonBar=null;
|
samer@0
|
68 private Vector windows=new Vector();
|
samer@0
|
69 private java.awt.Frame dialogOwner=null;
|
samer@0
|
70 private Hashtable winmap=new Hashtable();
|
samer@0
|
71
|
samer@0
|
72 protected JAppletShell()
|
samer@0
|
73 {
|
samer@0
|
74 vm = new ViewableManager();
|
samer@0
|
75 am = new AgentManager();
|
samer@0
|
76 am.registerAgent(am);
|
samer@0
|
77 am.registerAgent(this);
|
samer@0
|
78
|
samer@0
|
79 props = new Properties(Shell.env());
|
samer@0
|
80
|
samer@0
|
81 put(VDouble.class,DoubleViewer.class);
|
samer@0
|
82 put(VInteger.class,IntegerViewer.class);
|
samer@0
|
83 put(VBoolean.class,BooleanViewer.class);
|
samer@0
|
84 put(VString.class,StringViewer.class);
|
samer@0
|
85 put(VParameter.class,ParameterViewer.class);
|
samer@0
|
86 put(VFile.class,FileViewer.class);
|
samer@0
|
87 put(VColor.class,ColorButton.class);
|
samer@0
|
88 put(Variable.class,StringViewer.class);
|
samer@0
|
89 put(Viewable.class,DefaultViewer.class);
|
samer@0
|
90 }
|
samer@0
|
91
|
samer@0
|
92 public static void initialise(Applet applet)
|
samer@0
|
93 {
|
samer@0
|
94 System.out.println("Initialising JAppletShell...\n");
|
samer@0
|
95 synchronized(mutex) {
|
samer@0
|
96 if (instance==null) {
|
samer@0
|
97 Shell.setShell(instance=new JAppletShell());
|
samer@0
|
98 }
|
samer@0
|
99 instance.documentBase=applet.getDocumentBase();
|
samer@0
|
100 }
|
samer@0
|
101 }
|
samer@0
|
102
|
samer@0
|
103 public void getCommands(Agent.Registry r) {
|
samer@0
|
104 r.add("load").add("save").add("run").add("expose");
|
samer@0
|
105 }
|
samer@0
|
106
|
samer@0
|
107 public void execute(String cmd, Environment env) throws Exception
|
samer@0
|
108 {
|
samer@0
|
109 if (cmd.equals("load")) {
|
samer@0
|
110 loadargs(new URL(documentBase, X.string(env.datum(),"args")));
|
samer@0
|
111 } else if (cmd.equals("save")) {
|
samer@0
|
112 saveargs(new URL(documentBase, X.string(env.datum(),"args")));
|
samer@0
|
113 } else if (cmd.equals("run")) {
|
samer@0
|
114 String scr=X.string(env.datum("script"));
|
samer@0
|
115 runscript(new URL(documentBase, scr));
|
samer@0
|
116 } else if (cmd.equals("expose")) {
|
samer@0
|
117 exposeViewables();
|
samer@0
|
118 } else if (cmd.equals("exit")) {
|
samer@0
|
119 Shell.trace("Shell: exit");
|
samer@0
|
120 }
|
samer@0
|
121 }
|
samer@0
|
122
|
samer@0
|
123 public void exit() {}
|
samer@0
|
124
|
samer@0
|
125 public synchronized void loadargs(URL url) throws Exception
|
samer@0
|
126 {
|
samer@0
|
127 Shell.print("loading args from "+url);
|
samer@0
|
128 InputStream in=url.openConnection().getInputStream();
|
samer@0
|
129 try { props.load(new BufferedInputStream(in)); }
|
samer@0
|
130 finally { in.close(); }
|
samer@0
|
131 }
|
samer@0
|
132
|
samer@0
|
133 public synchronized void saveargs(URL url) throws Exception
|
samer@0
|
134 {
|
samer@0
|
135 URLConnection con=url.openConnection();
|
samer@0
|
136 con.setDoOutput(true);
|
samer@0
|
137
|
samer@0
|
138 OutputStream out=con.getOutputStream();
|
samer@0
|
139 try {
|
samer@0
|
140 Shell.print("saving args to "+url);
|
samer@0
|
141 props.save(out);
|
samer@0
|
142 Shell.print("-- saved");
|
samer@0
|
143 } finally { out.close(); }
|
samer@0
|
144 }
|
samer@0
|
145
|
samer@0
|
146 public void runscript(URL url) throws Exception
|
samer@0
|
147 {
|
samer@0
|
148 InputStream in=url.openStream();
|
samer@0
|
149 try { Shell.interpret(new BufferedReader(new InputStreamReader(in))); }
|
samer@0
|
150 finally { in.close(); }
|
samer@0
|
151 }
|
samer@0
|
152
|
samer@0
|
153 protected void put(Class a, Class b) { samer.core.Registry.put(a,b); }
|
samer@0
|
154
|
samer@0
|
155 // ----------- Window registry ----------
|
samer@0
|
156
|
samer@0
|
157 public static void registerWindow(Shell.Window win, String name)
|
samer@0
|
158 {
|
samer@0
|
159 if (name!=null) {
|
samer@0
|
160 Shell.trace("registering named window: "+name);
|
samer@0
|
161 instance.winmap.put(name,win);
|
samer@0
|
162 } else {
|
samer@0
|
163 Shell.trace("registering anonymous window: "+win);
|
samer@0
|
164 instance.windows.addElement(win);
|
samer@0
|
165 }
|
samer@0
|
166 }
|
samer@0
|
167
|
samer@0
|
168 public static void deregisterWindow(Shell.Window win, String name)
|
samer@0
|
169 {
|
samer@0
|
170 Shell.trace("deregistering window "+name);
|
samer@0
|
171 if (name!=null) {
|
samer@0
|
172 Object o=instance.winmap.get(name);
|
samer@0
|
173 if (win==o) instance.winmap.remove(name);
|
samer@0
|
174 } else instance.windows.removeElement(win);
|
samer@0
|
175 }
|
samer@0
|
176
|
samer@0
|
177 public static java.awt.Frame dummyFrame()
|
samer@0
|
178 {
|
samer@0
|
179 if (instance.dialogOwner==null) {
|
samer@0
|
180 instance.dialogOwner=new java.awt.Frame("DialogOwner");
|
samer@0
|
181 }
|
samer@0
|
182 return instance.dialogOwner;
|
samer@0
|
183 }
|
samer@0
|
184
|
samer@0
|
185 public Shell.Dialog getDialog(String title) {
|
samer@0
|
186 return new Dialog(dummyFrame(),title,true);
|
samer@0
|
187 }
|
samer@0
|
188
|
samer@0
|
189 public Shell.Window getWindow(String title)
|
samer@0
|
190 {
|
samer@0
|
191 Object win=instance.winmap.remove(title);
|
samer@0
|
192
|
samer@0
|
193 if (win==null) {
|
samer@0
|
194 // named window not found -- return first anonymous window
|
samer@0
|
195 if (windows.size()>0) {
|
samer@0
|
196 Shell.trace("looking for anonymous window");
|
samer@0
|
197 win=windows.firstElement();
|
samer@0
|
198 windows.removeElementAt(0);
|
samer@0
|
199 Shell.trace("returning anonymous window");
|
samer@0
|
200 }
|
samer@0
|
201 } else Shell.trace("returning named window: "+title);
|
samer@0
|
202
|
samer@0
|
203 // if all else fails, create a new Frame window
|
samer@0
|
204 if (win==null) win=new Frame(title);
|
samer@0
|
205
|
samer@0
|
206 return (Shell.Window)win;
|
samer@0
|
207 }
|
samer@0
|
208
|
samer@0
|
209 public Viewer getViewerFor(Viewable v) { return null; }
|
samer@0
|
210
|
samer@0
|
211 // different types of message
|
samer@0
|
212 public void status(String msg) { print(msg); }
|
samer@0
|
213 public void trace(String msg) { System.err.println(msg); }
|
samer@0
|
214 public void print(String msg)
|
samer@0
|
215 {
|
samer@0
|
216 if (console!=null) console.write(msg+"\n");
|
samer@0
|
217 else System.out.println(msg);
|
samer@0
|
218 }
|
samer@0
|
219
|
samer@0
|
220 public PrintWriter getPrintWriter() {
|
samer@0
|
221 if (console!=null) return new PrintWriter(console.getWriter(),true);
|
samer@0
|
222 else return new PrintWriter(System.out);
|
samer@0
|
223 }
|
samer@0
|
224
|
samer@0
|
225 // agents and viewables
|
samer@0
|
226 public void registerAgent(Agent a) { am.registerAgent(a); }
|
samer@0
|
227 public void deregisterAgent(Agent a) { am.deregisterAgent(a); }
|
samer@0
|
228 public void registerViewable(Viewable v) { vm.registerViewable(v); }
|
samer@0
|
229 public void deregisterViewable(Viewable v) { vm.deregisterViewable(v); }
|
samer@0
|
230
|
samer@0
|
231 public void registerButtons(Container c) {
|
samer@0
|
232 buttonBar = new ButtonBar(c);
|
samer@0
|
233 buttonBar.setBroadcaster(am.getBroadcaster());
|
samer@0
|
234 }
|
samer@0
|
235
|
samer@0
|
236 public void deregisterButtons(Container c) {
|
samer@0
|
237 if (buttonBar.container()==c) buttonBar=null;
|
samer@0
|
238 }
|
samer@0
|
239
|
samer@0
|
240 public Viewer createViewerPanel(Viewer vwr) { return new VPanel(vwr); }
|
samer@0
|
241 public Component createLabel(String txt) {
|
samer@0
|
242 Label l=new Label(txt);
|
samer@0
|
243 l.addMouseListener(MouseRetarget.listener);
|
samer@0
|
244 return l;
|
samer@0
|
245 }
|
samer@0
|
246
|
samer@0
|
247 public Container createButtonsFor(Agent agent)
|
samer@0
|
248 {
|
samer@0
|
249 ButtonBar bbar=new ButtonBar();
|
samer@0
|
250 bbar.setTarget(agent);
|
samer@0
|
251 agent.getCommands(bbar);
|
samer@0
|
252 return bbar.container();
|
samer@0
|
253 }
|
samer@0
|
254
|
samer@0
|
255 public NumberViewer createNumberViewer(String label, int flags, NumberSink s) {
|
samer@0
|
256 return new TextualNumberViewer(label,flags,s);
|
samer@0
|
257 }
|
samer@0
|
258
|
samer@0
|
259 public void exposeCommands( Agent agent)
|
samer@0
|
260 {
|
samer@0
|
261 // what happens if button container goes away?
|
samer@0
|
262
|
samer@0
|
263 if (buttonBar!=null) {
|
samer@0
|
264 buttonBar.setTarget(agent); // ?? or broadcast?
|
samer@0
|
265 agent.getCommands(buttonBar);
|
samer@0
|
266 buttonBar.container().getParent().validate();
|
samer@0
|
267 }
|
samer@0
|
268
|
samer@0
|
269 // should we put buttons on console if no button bar?
|
samer@0
|
270 }
|
samer@0
|
271
|
samer@0
|
272 // ----------- Viewables management --------------
|
samer@0
|
273
|
samer@0
|
274 public static void expose() { instance.exposeViewables(); }
|
samer@0
|
275
|
samer@0
|
276 public void exposeViewables()
|
samer@0
|
277 {
|
samer@0
|
278 if (!vm.hasViewerContainer()) {
|
samer@0
|
279 // try to find window called "exposed"
|
samer@0
|
280 Shell.Window win=(Shell.Window)instance.winmap.remove("exposed");
|
samer@0
|
281 if (win==null) {
|
samer@0
|
282 // window not found-use new frame window
|
samer@0
|
283 vm.exposeViewables(new VContainer(new Frame("exposed")));
|
samer@0
|
284 } else {
|
samer@0
|
285 // use named window
|
samer@0
|
286 vm.exposeViewables(new VContainer(win));
|
samer@0
|
287 }
|
samer@0
|
288 }
|
samer@0
|
289 }
|
samer@0
|
290
|
samer@0
|
291 class VContainer extends WindowAdapter implements ViewableManager.ViewerContainer
|
samer@0
|
292 {
|
samer@0
|
293 Shell.Window win;
|
samer@0
|
294 Frame frame;
|
samer@0
|
295
|
samer@0
|
296 VContainer(Frame frame) { this((Shell.Window)frame); this.frame=frame; }
|
samer@0
|
297 VContainer(Shell.Window win)
|
samer@0
|
298 {
|
samer@0
|
299 frame=null;
|
samer@0
|
300
|
samer@0
|
301 this.win=win;
|
samer@0
|
302 // let applet control this?
|
samer@0
|
303 win.container().setLayout( new StackLayout());
|
samer@0
|
304 win.expose(); // redundant for applets
|
samer@0
|
305 win.addWindowListener(this); // also redundant!
|
samer@0
|
306 }
|
samer@0
|
307
|
samer@0
|
308 public void add(java.util.Iterator components)
|
samer@0
|
309 {
|
samer@0
|
310 Shell.trace("VContainer: adding stuff");
|
samer@0
|
311 Container c=win.container();
|
samer@0
|
312 while (components.hasNext()) {
|
samer@0
|
313 c.add((Component)(components.next()));
|
samer@0
|
314 }
|
samer@0
|
315 c.validate();
|
samer@0
|
316 if (frame!=null) frame.pack();
|
samer@0
|
317 }
|
samer@0
|
318
|
samer@0
|
319 public void removeAll() { win.container().removeAll(); }
|
samer@0
|
320 public void windowClosing(WindowEvent e) {
|
samer@0
|
321 vm.releaseViewerContainer();
|
samer@0
|
322 win.dispose();
|
samer@0
|
323 }
|
samer@0
|
324 }
|
samer@0
|
325
|
samer@0
|
326 // --------------- Console management -------------
|
samer@0
|
327
|
samer@0
|
328 public void releaseConsoleContainer(Container c)
|
samer@0
|
329 {
|
samer@0
|
330 // if we're using this console container...
|
samer@0
|
331 if (confr==c) {
|
samer@0
|
332 confr.removeAll();
|
samer@0
|
333 confr=null;
|
samer@0
|
334
|
samer@0
|
335 // should we destroy the console too?
|
samer@0
|
336 // what about any outstanding PrintWriters?
|
samer@0
|
337 }
|
samer@0
|
338 }
|
samer@0
|
339
|
samer@0
|
340 public void setConsoleContainer(Container c)
|
samer@0
|
341 {
|
samer@0
|
342 // we have a console container - don't need a new one
|
samer@0
|
343 if (confr!=null) return;
|
samer@0
|
344 confr = c;
|
samer@0
|
345
|
samer@0
|
346 // create console if necessary
|
samer@0
|
347 if (console==null) console = new Console();
|
samer@0
|
348
|
samer@0
|
349 // add console, command field and button bar according
|
samer@0
|
350 // to current property set.
|
samer@0
|
351
|
samer@0
|
352 confr.setLayout( new BorderLayout(3,3));
|
samer@0
|
353 confr.add(console, "Center");
|
samer@0
|
354 if (Shell.getBoolean("console.commandField",false)) {
|
samer@0
|
355 confr.add( new CommandField(20), "South");
|
samer@0
|
356 }
|
samer@0
|
357
|
samer@0
|
358 // add button bar if buttons not already showing.
|
samer@0
|
359 if (buttonBar!=null && !buttonBar.container().isShowing()) {
|
samer@0
|
360 confr.add( buttonBar.container(), "North");
|
samer@0
|
361 confr.validate();
|
samer@0
|
362 }
|
samer@0
|
363 }
|
samer@0
|
364 }
|