Java Source Code: org.opensourcephysics.davidson.applets.ApplicationApplet


   1: /*
   2:  * Open Source Physics software is free software as described near the bottom of this code file.
   3:  *
   4:  * For additional information and documentation on Open Source Physics please see:
   5:  * <http://www.opensourcephysics.org/>
   6:  */
   7: 
   8: package org.opensourcephysics.davidson.applets;
   9: import java.lang.reflect.*;
  10: import java.util.*;
  11: import java.awt.*;
  12: import java.awt.event.*;
  13: import javax.swing.*;
  14: import org.opensourcephysics.display.*;
  15: import org.opensourcephysics.controls.MessageFrame;
  16: import org.opensourcephysics.controls.OSPLog;
  17: import org.opensourcephysics.tools.ResourceLoader;
  18: import org.opensourcephysics.tools.Resource;
  19: 
  20: /**
  21:  * ApplicationApplet displays a button that invokes a static main method in a target class.
  22:  * This Applet can be used to run applications as applets.  Security restrictions may cause some
  23:  * progrgrams to malfunction if the jar file is not signed.
  24:  *
  25:  * @version    0.9 beta
  26:  * @author     Wolfgang Chrstiain
  27:  * @created    October 06, 2005
  28:  */
  29:	  public class ApplicationApplet extends JApplet {
  30:
  31:   JFrame mainFrame = null;
  32:   JButton showFramesButton = new JButton("Show");
  33:   String targetClassName;
  34:   ArrayList newFrames = new ArrayList();
  35:   ArrayList existingFrames = new ArrayList();
  36:   Class target;
  37:   String[] args = null;
  38:   boolean singleApp = false;
  39:   String targetError=null;
  40:
  41:   /**
  42:    *  Gets the parameter attribute of the ApplicationApplet object
  43:    *
  44:    * @param  key  Description of Parameter
  45:    * @param  def  Description of Parameter
  46:    * @return      The parameter value
  47:    */
  48:	     public String getParameter(String key, String def) {
  49:      return((getParameter(key)!=null)
  50:             ? getParameter(key)
  51:             : def);
  52:   }
  53:
  54:   /**
  55:    *  Initializes the applet
  56:    */
  57:	     public void init() {
  58:      super.init();
  59:      OSPFrame.applet = this;
  60:      OSPFrame.appletMode = false; // This insures that ALL frames are made visible when the applet is launched.
  61:	        if(getParameter("showLog", "false").toLowerCase().trim().equals("true")){
  62:         OSPLog.showLog();
  63:      }
  64:      String arg0 = getParameter("xmldata", null);
  65:      arg0 = getParameter("args[0]", arg0);
  66:	        if(arg0!=null) {
  67:         args = new String[1];
  68:      }
  69:      String arg1 = getParameter("args[1]", null);
  70:      String arg2 = getParameter("args[2]", null);
  71:	        if(arg2!=null) {
  72:         args = new String[3];
  73:         args[0] = arg0;
  74:         args[1] = arg1;
  75:         args[2] = arg2;
  76:      }else if(arg1!=null) {
  77:         args = new String[2];
  78:         args[0] = arg0;
  79:         args[1] = arg1;
  80:      }else if(arg0!=null) {
  81:         args = new String[1];
  82:         args[0] = arg0;
  83:      }
  84:      targetClassName = getParameter("target", null);
  85:	        if(targetClassName==null) {
  86:         targetClassName = getParameter("app", null);
  87:      }
  88:	        if(targetClassName==null){
  89:         readManifest();
  90:      }
  91:      String title = getParameter("title", null);
  92:      singleApp = getParameter("singleapp", "false").trim().equalsIgnoreCase("true");
  93:	        if(title==null) {
  94:         String[] s = targetClassName.split("[\056]"); // period character
  95:         showFramesButton.setText(s[s.length-1]);
  96:      } else {
  97:         showFramesButton.setText(title);
  98:      }
  99:      getRootPane().getContentPane().add(showFramesButton, BorderLayout.CENTER);
 100:      showFramesButton.addActionListener(new DisplayBtnListener());
 101:   }
 102:
 103:   /**
 104:    * Determines whether the specified class is launchable.
 105:    *
 106:    * @param type the launch class to verify
 107:    * @return <code>true</code> if the class is launchable
 108:    */
 109:	     static boolean isLaunchable(Class type) {
 110:	        if(type==null) {
 111:         return false;
 112:      }
 113:	        try {
 114:         // throws exception if method not found; return value not used
 115:         type.getMethod("main", new Class[]{String[].class});
 116:         return true;
 117:      } catch(NoSuchMethodException ex) {
 118:         return false;
 119:      }
 120:   }
 121:
 122:   /**
 123:    *  Destroys the applet's resources.
 124:    */
 125:	     public void destroy() {
 126:      disposeOwnedFrames();
 127:      target = null;
 128:      mainFrame = null;
 129:      super.destroy();
 130:   }
 131:
 132:	     private void readManifest(){
 133:      //String launchJar = ResourceLoader.getLaunchJarPath();
 134:      //System.out.println(launchJar);
 135:      String archive = getParameter("archive", null);
 136:      archive= archive.split(";")[0];
 137:      OSPLog.finer("archive applet tag="+archive);
 138:      if(archive==null) return;
 139:      String name = "META-INF/MANIFEST.MF";
 140:      Resource res = ResourceLoader.getResource(archive, name);
 141:	        if(res==null){
 142:         OSPLog.fine("manifest not found in="+archive);
 143:         return;
 144:      }
 145:      String manifest=res.getString();
 146:      String[] lines= manifest.split("\n");
 147:	        for(int i=0, n=Math.min(10,lines.length); i<n; i++){
 148:         int index=lines[i].indexOf("Main-Class:");
 149:	           if(index>=0){
 150:         targetClassName=lines[i].substring("Main-Class:".length()+index).trim();
 151:         OSPLog.fine("target class in manifest="+targetClassName);
 152:         return;
 153:         }
 154:    }
 155:   }
 156:
 157:
 158:	     private Class createTarget() {
 159:      Class type = null;
 160:      targetError=null;
 161:      // create the class loader
 162:      // ClassLoader classLoader = URLClassLoader.newInstance(new URL[] {getCodeBase()});
 163:      ClassLoader classLoader = getClass().getClassLoader();
 164:	        try {
 165:         type = classLoader.loadClass(targetClassName);
 166:      } catch(ClassNotFoundException ex1) {
 167:         System.err.println("Class not found: "+targetClassName);
 168:         targetError="Class not found: "+targetClassName;
 169:         return null;
 170:      }
 171:	        if(!isLaunchable(type)) {
 172:         System.err.println("Main method not found in "+targetClassName);
 173:         targetError="Main method not found in "+targetClassName;
 174:         return null;
 175:      }
 176:      // get the exisitng frames
 177:      Frame[] frame = Frame.getFrames();
 178:      existingFrames.clear();
 179:	        for(int i = 0, n = frame.length; i<n; i++) {
 180:         existingFrames.add(frame[i]);
 181:      }
 182:      // load html data file
 183:      String htmldata = getParameter("htmldata", null);
 184:	        if(htmldata!=null) {
 185:         TextFrame htmlframe = new TextFrame(htmldata, type);
 186:         htmlframe.setVisible(true);
 187:      }
 188:      // launch the app by invoking main method
 189:	        try {
 190:         Method m = type.getMethod("main", new Class[]{String[].class});
 191:         m.invoke(type, new Object[]{args});
 192:         frame = Frame.getFrames();
 193:	           for(int i = 0, n = frame.length; i<n; i++) {
 194:	              if((frame[i] instanceof JFrame)&&((JFrame) frame[i]).getDefaultCloseOperation()==JFrame.EXIT_ON_CLOSE) {
 195:               ((JFrame) frame[i]).setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
 196:	                 if(mainFrame==null) {
 197:                  mainFrame = (JFrame) frame[i]; // assume this is the main application frame
 198:               }
 199:            }
 200:	              if(!existingFrames.contains(frame[i])) {
 201:               // manage new frames
 202:               newFrames.add(frame[i]);
 203:            }
 204:         }
 205:      } catch(NoSuchMethodException ex) {
 206:         System.err.println(ex);
 207:         targetError=ex.toString();
 208:      } catch(InvocationTargetException ex) {
 209:         System.err.println(ex);
 210:         targetError=ex.toString();
 211:      } catch(IllegalAccessException ex) {
 212:         System.err.println(ex);
 213:         targetError=ex.toString();
 214:      }
 215:      return type;
 216:   }
 217:
 218:	     private class DisplayBtnListener implements ActionListener {
 219:
 220:	        public void actionPerformed(ActionEvent e) {
 221:	           if(singleApp&&(OSPFrame.applet!=ApplicationApplet.this)) {
 222:            disposeOwnedFrames();
 223:            target = null;
 224:            mainFrame = null;
 225:            OSPFrame.applet = ApplicationApplet.this;
 226:         }
 227:	           if(target==null) {
 228:            target = createTarget();
 229:            if(targetError!=null) target=null;
 230:         } else {
 231:            Iterator it = newFrames.iterator();
 232:	              while(it.hasNext()) {
 233:               Frame frame = ((Frame) it.next());
 234:	                 if(frame.isDisplayable()&&!(frame instanceof OSPLog)&&!(frame instanceof MessageFrame)) {
 235:                  frame.setVisible(true);
 236:               }
 237:            }
 238:         }
 239:	           if(mainFrame!=null) {
 240:            mainFrame.setState(Frame.NORMAL);
 241:            mainFrame.setVisible(true);
 242:            mainFrame.toFront();
 243:         }
 244:      }
 245:   }
 246:
 247:	     private void disposeOwnedFrames() {
 248:      Frame frame[] = Frame.getFrames();
 249:	        for(int i = 0, n = frame.length; i<n; i++) {
 250:	           if(frame[i].getClass().getName().startsWith("sun.plugin")) {
 251:            continue; // don't mess with plugin
 252:         }
 253:	           if((frame[i] instanceof JFrame)&&((JFrame) frame[i]).getDefaultCloseOperation()==JFrame.EXIT_ON_CLOSE) {
 254:            ((JFrame) frame[i]).setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
 255:         }
 256:	           if(!existingFrames.contains(frame[i])) {
 257:            frame[i].setVisible(false);
 258:            frame[i].dispose();
 259:         }
 260:      }
 261:      newFrames.clear();
 262:   }
 263:}
 264:/*
 265: * Open Source Physics software is free software; you can redistribute
 266: * it and/or modify it under the terms of the GNU General Public License (GPL) as
 267: * published by the Free Software Foundation; either version 2 of the License,
 268: * or(at your option) any later version.
 269: *
 270: * Code that uses any portion of the code in the org.opensourcephysics package
 271: * or any subpackage (subdirectory) of this package must must also be be released
 272: * under the GNU GPL license.
 273: *
 274: * This software is distributed in the hope that it will be useful,
 275: * but WITHOUT ANY WARRANTY; without even the implied warranty of
 276: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 277: * GNU General Public License for more details.
 278: *
 279: * You should have received a copy of the GNU General Public License
 280: * along with this; if not, write to the Free Software
 281: * Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA
 282: * or view the license online at http://www.gnu.org/copyleft/gpl.html
 283: *
 284: * Copyright (c) 2007  The Open Source Physics project
 285: *                     http://www.opensourcephysics.org
 286: */