001/* ----------------------------------------------------------------------------
002   The Kiwi Toolkit - A Java Class Library
003   Copyright (C) 1998-2004 Mark A. Lindner
004
005   This library is free software; you can redistribute it and/or
006   modify it under the terms of the GNU General Public License as
007   published by the Free Software Foundation; either version 2 of the
008   License, or (at your option) any later version.
009
010   This library is distributed in the hope that it will be useful,
011   but WITHOUT ANY WARRANTY; without even the implied warranty of
012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013   General Public License for more details.
014
015   You should have received a copy of the GNU General Public License
016   along with this library; if not, write to the Free Software
017   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
018   02111-1307, USA.
019 
020   The author may be contacted at: mark_a_lindner@yahoo.com
021   ----------------------------------------------------------------------------
022   $Log: AppletPanel.java,v $
023   Revision 1.4  2004/05/06 00:46:52  markl
024   comment block updates
025
026   Revision 1.3  2003/06/02 06:49:44  markl
027   Added applet map management to context.
028
029   Revision 1.2  2003/06/01 11:08:55  markl
030   Final refinements for release 1.4.2
031   ----------------------------------------------------------------------------
032*/
033
034package kiwi.ui.applet;
035
036import java.awt.*;
037import java.io.*;
038import java.net.*;
039import java.util.*;
040import javax.swing.*;
041
042import kiwi.ui.*;
043import kiwi.util.*;
044
045/** A component for displaying Java applets in a standalone Java
046  * application.  This class provides a basic execution context for
047  * Java applets; this context is fully functional with one exception:
048  * requests from the applet to open a document are ignored.
049  * <p>
050  * Only applets which subclass <code>JApplet</code> are supported by this
051  * class; an attempt to load a "heavyweight" applet (one that extends
052  * <code>Applet</code>) will result in an exception.
053  * <p>
054  * The applet must be provided in the form of a self-contained JAR
055  * file, which includes the applet's classes as well as any resources
056  * (such as images and audio clips) that are needed by the
057  * applet. These resources may be fetched by the applet using the
058  * customary <code>getAudioClip()</code> and <code>getImage()</code>
059  * methods. The <code>getCodeBase()</code> and <code>getDocumentBase()</code>
060  * methods return a URL representing the applet JAR file itself, and can
061  * thus be used to construct URLs to the applet's resources.
062  * <p>
063  * The panel will attempt to resize itself to accommodate the size of its
064  * applet.
065  *
066  * <p><center>
067  * <img src="snapshot/AppletPanel.gif"><br>
068  * <i>An example AppletPanel.</i>
069  * </center>
070  *
071  * @author Mark Lindner
072  * @since Kiwi 1.4.2
073  */
074
075public class AppletPanel extends KPanel
076  {
077  private KiwiAppletContext ctx;
078  private KiwiAppletStub stub; 
079  private JApplet applet;
080  private KPanel p_applet;
081  private JTextField t_status;
082  private String appletName = null;
083
084  /** Construct a new <code>AppletPanel</code>. The panel consists of the
085    * applet itself (if one has been set) and a status area in which
086    * status messages from the applet are displayed.
087    * <p>
088    * In the current implementation, each <code>AppletPanel</code> has
089    * its own applet context; therefore applets cannot interact with
090    * each other. This may be changed in a future release.
091    */
092  
093  public AppletPanel()
094    {
095    setLayout(new BorderLayout(5, 5));
096    
097    ctx = new KiwiAppletContext()
098        {
099        public void showStatus(String msg)
100          {
101          t_status.setText(msg);
102          }
103        };
104
105    p_applet = new KPanel();
106    p_applet.setOpaque(true);
107    p_applet.setBackground(Color.black);
108    p_applet.setLayout(new GridLayout(1, 0));
109    
110    add("Center", p_applet);
111
112    t_status = new JTextField();
113    t_status.setOpaque(false);
114    t_status.setEditable(false);
115    t_status.setFocusable(false);
116
117    add("South", t_status);
118
119    setBorder(KiwiUtils.defaultBorder);
120    }
121
122  /** Request focus for this component. Overridden to transfer focus to the
123    *  applet.
124    */
125
126  public void requestFocus()
127    {
128    if(applet != null)
129      applet.requestFocus();
130    else
131      super.requestFocus();
132    }
133  
134  /*
135   */
136  
137  void setStatus(String text)
138    {
139    t_status.setText(text);
140    }
141
142  /** Remove the current applet (if any) from the panel. The applet will be
143    * stopped, destroyed, and removed from the panel.
144    */
145
146  public void removeApplet()
147    {
148    if(applet == null)
149      return;
150
151    if(appletName != null)
152      ctx.removeApplet(appletName);
153    
154    stopApplet();
155    applet.setStub(null);
156    p_applet.removeAll();
157    applet = null;
158    }
159  
160  /** Set the applet to be displayed by this panel. 
161    *
162    * @param archive The path to the JAR file containing the applet's classes
163    * and resources.
164    * @param className The fully-qualified name of the class which implements
165    * the <code>JApplet</code> interface.
166    * @param width The preferred width of the applet.
167    * @param height The preferred height of the applet.
168    * @param params The parameters for the applet.
169    * @throws AppletException If the applet could not be loaded. This is a
170    * chained exception; the <code>getCause()</code> method will return the
171    * original exception.
172    */
173
174  public void setApplet(String archive, String className, int width,
175                        int height, Dictionary params) throws AppletException
176    {
177    setApplet(new File(archive), className, width, height, params);
178    }
179  
180  /** Set the applet to be displayed by this panel. 
181    *
182    * @param archive The JAR file containing the applet's classes and
183    * resources.
184    * @param className The fully-qualified name of the class which implements
185    * the <code>JApplet</code> interface.
186    * @param width The preferred width of the applet.
187    * @param height The preferred height of the applet.
188    * @param params The parameters for the applet.
189    * @throws AppletException If the applet could not be loaded. This
190    * is a chained exception; the <code>getCause()</code> method will
191    * return the original exception.
192    */
193  
194  public void setApplet(File archive, String className, int width,
195                        int height, Dictionary params) throws AppletException
196    {
197    URL url = null;
198
199    removeApplet();
200    
201    try
202      {
203      url = new URL("jar:file:" + archive.getAbsolutePath() + "!/");
204      }
205    catch(MalformedURLException ex)
206      {
207      throw new AppletException(ex);
208      }
209    
210    ClassLoader classLoader = new URLClassLoader(new URL[] { url });
211
212    Class clazz = null;
213
214    try
215      {
216      clazz = classLoader.loadClass(className);
217      applet = (JApplet)clazz.newInstance();
218      stub = new KiwiAppletStub(this, ctx, url, params);
219      applet.setStub(stub);
220      applet.setFocusable(true);
221
222      p_applet.setPreferredSize(new Dimension(width, height));
223      p_applet.add(applet);
224
225      appletName = className;
226      ctx.addApplet(appletName, applet);
227      }
228    catch(Exception ex)
229      {
230      throw new AppletException(ex);
231      }
232    }
233
234  /** Start execution of the applet (if one has been set). The
235   *  applet's <code>init()</code> and <code>start()</code> methods are
236   *  invoked, in that order.
237   */
238  
239  public void startApplet()
240    {
241    if(applet != null)
242      {
243      applet.init();
244      applet.start();
245
246      setStatus("Applet started.");
247      }
248    }
249
250  /** Stop execution of the applet (if one has been set). The applet's
251   *  <code>stop()</code> and <code>destroy()</code> methods are invoked, in
252   *  that order.
253   */
254  
255  public void stopApplet()
256    {
257    if(applet != null)
258      {
259      applet.stop();
260      applet.destroy();
261
262      setStatus("Applet stopped.");
263      }
264    }
265  
266  }
267
268/* end of source file */