Mercurial > hg > jslab
view 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 |
line wrap: on
line source
/* * JAppletShell.java * * Copyright (c) 2000, Samer Abdallah, King's College London. * All rights reserved. * * This software is provided AS iS and WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. */ package samer.applet; import java.applet.*; import java.awt.*; import java.awt.event.*; import java.util.*; import java.net.*; import java.io.*; import samer.core.*; import samer.core.util.heavy.*; import samer.core.util.shell.*; import samer.core.util.*; import samer.core.Shell.*; import samer.core.util.heavy.Frame; import samer.core.util.heavy.Dialog; import samer.core.util.Properties; import samer.core.NumberViewer; import samer.core.viewers.*; import samer.core.types.*; import samer.core.util.heavy.Console; import java.util.Hashtable; /* To do: o 2 - Create optional output window 3 - display commands in menu on Applet OR 4 - commands on button bar in applet 6 - create Viewer to use Tools 7 - manage agents 8 - manage viewables */ /** This is a Shell that uses Applets to form a GUI. The basic idea is that each applet that gets created on a web page registers itself with shell as an available window, or perhaps as a special window like a console or viewables container. Then, whenever a script or something asks for a window, it gets to use one of the applets. */ public class JAppletShell implements Shell.Interface, Agent { static JAppletShell instance=null; private static Object mutex=new Object(); // to serialise Shell creation private AgentManager am; private ViewableManager vm; private Properties props; private URL documentBase; private Container confr=null; private Console console=null; private ButtonBar buttonBar=null; private Vector windows=new Vector(); private java.awt.Frame dialogOwner=null; private Hashtable winmap=new Hashtable(); protected JAppletShell() { vm = new ViewableManager(); am = new AgentManager(); am.registerAgent(am); am.registerAgent(this); props = new Properties(Shell.env()); put(VDouble.class,DoubleViewer.class); put(VInteger.class,IntegerViewer.class); put(VBoolean.class,BooleanViewer.class); put(VString.class,StringViewer.class); put(VParameter.class,ParameterViewer.class); put(VFile.class,FileViewer.class); put(VColor.class,ColorButton.class); put(Variable.class,StringViewer.class); put(Viewable.class,DefaultViewer.class); } public static void initialise(Applet applet) { System.out.println("Initialising JAppletShell...\n"); synchronized(mutex) { if (instance==null) { Shell.setShell(instance=new JAppletShell()); } instance.documentBase=applet.getDocumentBase(); } } public void getCommands(Agent.Registry r) { r.add("load").add("save").add("run").add("expose"); } public void execute(String cmd, Environment env) throws Exception { if (cmd.equals("load")) { loadargs(new URL(documentBase, X.string(env.datum(),"args"))); } else if (cmd.equals("save")) { saveargs(new URL(documentBase, X.string(env.datum(),"args"))); } else if (cmd.equals("run")) { String scr=X.string(env.datum("script")); runscript(new URL(documentBase, scr)); } else if (cmd.equals("expose")) { exposeViewables(); } else if (cmd.equals("exit")) { Shell.trace("Shell: exit"); } } public void exit() {} public synchronized void loadargs(URL url) throws Exception { Shell.print("loading args from "+url); InputStream in=url.openConnection().getInputStream(); try { props.load(new BufferedInputStream(in)); } finally { in.close(); } } public synchronized void saveargs(URL url) throws Exception { URLConnection con=url.openConnection(); con.setDoOutput(true); OutputStream out=con.getOutputStream(); try { Shell.print("saving args to "+url); props.save(out); Shell.print("-- saved"); } finally { out.close(); } } public void runscript(URL url) throws Exception { InputStream in=url.openStream(); try { Shell.interpret(new BufferedReader(new InputStreamReader(in))); } finally { in.close(); } } protected void put(Class a, Class b) { samer.core.Registry.put(a,b); } // ----------- Window registry ---------- public static void registerWindow(Shell.Window win, String name) { if (name!=null) { Shell.trace("registering named window: "+name); instance.winmap.put(name,win); } else { Shell.trace("registering anonymous window: "+win); instance.windows.addElement(win); } } public static void deregisterWindow(Shell.Window win, String name) { Shell.trace("deregistering window "+name); if (name!=null) { Object o=instance.winmap.get(name); if (win==o) instance.winmap.remove(name); } else instance.windows.removeElement(win); } public static java.awt.Frame dummyFrame() { if (instance.dialogOwner==null) { instance.dialogOwner=new java.awt.Frame("DialogOwner"); } return instance.dialogOwner; } public Shell.Dialog getDialog(String title) { return new Dialog(dummyFrame(),title,true); } public Shell.Window getWindow(String title) { Object win=instance.winmap.remove(title); if (win==null) { // named window not found -- return first anonymous window if (windows.size()>0) { Shell.trace("looking for anonymous window"); win=windows.firstElement(); windows.removeElementAt(0); Shell.trace("returning anonymous window"); } } else Shell.trace("returning named window: "+title); // if all else fails, create a new Frame window if (win==null) win=new Frame(title); return (Shell.Window)win; } public Viewer getViewerFor(Viewable v) { return null; } // different types of message public void status(String msg) { print(msg); } public void trace(String msg) { System.err.println(msg); } public void print(String msg) { if (console!=null) console.write(msg+"\n"); else System.out.println(msg); } public PrintWriter getPrintWriter() { if (console!=null) return new PrintWriter(console.getWriter(),true); else return new PrintWriter(System.out); } // agents and viewables public void registerAgent(Agent a) { am.registerAgent(a); } public void deregisterAgent(Agent a) { am.deregisterAgent(a); } public void registerViewable(Viewable v) { vm.registerViewable(v); } public void deregisterViewable(Viewable v) { vm.deregisterViewable(v); } public void registerButtons(Container c) { buttonBar = new ButtonBar(c); buttonBar.setBroadcaster(am.getBroadcaster()); } public void deregisterButtons(Container c) { if (buttonBar.container()==c) buttonBar=null; } public Viewer createViewerPanel(Viewer vwr) { return new VPanel(vwr); } public Component createLabel(String txt) { Label l=new Label(txt); l.addMouseListener(MouseRetarget.listener); return l; } public Container createButtonsFor(Agent agent) { ButtonBar bbar=new ButtonBar(); bbar.setTarget(agent); agent.getCommands(bbar); return bbar.container(); } public NumberViewer createNumberViewer(String label, int flags, NumberSink s) { return new TextualNumberViewer(label,flags,s); } public void exposeCommands( Agent agent) { // what happens if button container goes away? if (buttonBar!=null) { buttonBar.setTarget(agent); // ?? or broadcast? agent.getCommands(buttonBar); buttonBar.container().getParent().validate(); } // should we put buttons on console if no button bar? } // ----------- Viewables management -------------- public static void expose() { instance.exposeViewables(); } public void exposeViewables() { if (!vm.hasViewerContainer()) { // try to find window called "exposed" Shell.Window win=(Shell.Window)instance.winmap.remove("exposed"); if (win==null) { // window not found-use new frame window vm.exposeViewables(new VContainer(new Frame("exposed"))); } else { // use named window vm.exposeViewables(new VContainer(win)); } } } class VContainer extends WindowAdapter implements ViewableManager.ViewerContainer { Shell.Window win; Frame frame; VContainer(Frame frame) { this((Shell.Window)frame); this.frame=frame; } VContainer(Shell.Window win) { frame=null; this.win=win; // let applet control this? win.container().setLayout( new StackLayout()); win.expose(); // redundant for applets win.addWindowListener(this); // also redundant! } public void add(java.util.Iterator components) { Shell.trace("VContainer: adding stuff"); Container c=win.container(); while (components.hasNext()) { c.add((Component)(components.next())); } c.validate(); if (frame!=null) frame.pack(); } public void removeAll() { win.container().removeAll(); } public void windowClosing(WindowEvent e) { vm.releaseViewerContainer(); win.dispose(); } } // --------------- Console management ------------- public void releaseConsoleContainer(Container c) { // if we're using this console container... if (confr==c) { confr.removeAll(); confr=null; // should we destroy the console too? // what about any outstanding PrintWriters? } } public void setConsoleContainer(Container c) { // we have a console container - don't need a new one if (confr!=null) return; confr = c; // create console if necessary if (console==null) console = new Console(); // add console, command field and button bar according // to current property set. confr.setLayout( new BorderLayout(3,3)); confr.add(console, "Center"); if (Shell.getBoolean("console.commandField",false)) { confr.add( new CommandField(20), "South"); } // add button bar if buttons not already showing. if (buttonBar!=null && !buttonBar.container().isShowing()) { confr.add( buttonBar.container(), "North"); confr.validate(); } } }