annotate src/samer/applet/JAppletShell.java @ 8:5e3cbbf173aa tip

Reorganise some more
author samer
date Fri, 05 Apr 2019 22:41:58 +0100
parents bf79fb79ee13
children
rev   line source
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 }