comparison src/samer/applet/JAppletShell.java @ 0:bf79fb79ee13

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