Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 2 of 6
| Note |
|---|
| Check out Resources to obtain either a free copy of InstallAnywhere 5 Now! or an evaluation copy of another edition. The evaluation copies let you create installers that work for three days only. |
To effectively use InstallAnywhere, you should understand the InstallAnywhere user guide's core concepts before interacting with the tool:
public static void main(String [] args) method. A virtual machine may also be included, which the installer and LaunchAnywhere-created program will use. If not included,
the installer searches the platform during installation for an appropriate virtual machine. InstallAnywhere creates executable
installers for Windows 95, 98, Me, NT, 2000, and XP, and Solaris, Linux, HP-UX, AIX, Mac OS, and Mac OS X.
java command with the jar file. Create JAR-based installers for those platforms (such as OS/2, Windows NT for Alpha, VMS (Virtual
Memory System), and MVS (Multiple Virtual Storage)) that have no InstallAnywhere executable installer support.
.iap_xml files that record project-specific settings, such as a list of filenames for all files to be installed. For example, Lines.iap_xml identifies the project file for a Lines installer project. InstallAnywhere creates a folder for each project and places the
project file in that folder.
| Note |
|---|
| InstallAnywhere supports these additional core concepts: API, variables, SpeedFolder, installer localization, silent mode, and console mode. Consult the InstallAnywhere user guide to learn more about those concepts. |
"Tools of the Trade, Part 1" introduced you to the Lines applet. Although I would like us to create installers for that applet, we cannot because InstallAnywhere
supports the creation of installers for Java applications but not Java applets. We need a way to transform that applet to
an equivalent application. One way to accomplish that task exists in my first Java 101 column, "Applications, Applets, and Hybrids." In that article, I introduced you to the hybrid (part applet and part application) program category. By using that article's
Hybrid source code as a template, I transformed Lines the applet into Lines the hybrid, as Lines.java's source code shows:
Lines.java
// Lines.java
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.*;
public class Lines extends Applet implements Runnable
{
static Lines l;
static Stub s;
private int width = 0, height = 0;
private Thread runner = null;
private final static int MAXCOLORS = 256;
private final static int SLEEPMILLIS = 50;
public void init ()
{
// Acquire the applet's width and height.
width = getSize ().width;
height = getSize ().height;
}
public void start ()
{
// If no thread exists, create a Thread object that associates with the
// current Lines object, and start a new thread that invokes the current
// Lines object's run() method.
if (runner == null)
{
runner = new Thread (this);
runner.start ();
}
}
public void paint (Graphics g)
{
// Generate a random color and establish that color as the Graphics
// context's drawing color.
Color c = new Color (rnd (MAXCOLORS), rnd (MAXCOLORS), rnd (MAXCOLORS));
g.setColor (c);
// Generate a random set of coordinates in the upper-left quadrant of
// the drawing surface, and use those coordinates as the starting
// coordinates for a new line.
int x1 = rnd (width / 2);
int y1 = rnd (height / 2);
// Compute the line's ending coordinates by mirroring the starting
// coordinates in the lower-right quadrant.
int x2 = width - x1;
int y2 = height - y1;
// Draw the line.
g.drawLine (x1, y1, x2, y2);
// Draw an inverse of the line (for symmetry).
g.drawLine (x1, y2, x2, y1);
}
static int rnd (int limit)
{
// Return a random integer that ranges from 0 through limit-1.
return (int) (Math.random () * limit);
}
public void run ()
{
// Obtain a reference to the thread that was started in the applet's
// start() method.
Thread current = Thread.currentThread ();
// As long as runner contains the same reference, keep looping. The
// reference in runner becomes null when the applet's stop() method
// executes.
while (current == runner)
{
// Invoke the paint(Graphics g) method to draw another
// randomly colored and randomly positioned line.
repaint ();
// Pause for SLEEPMILLIS milliseconds to achieve an eye-pleasing
// display.
try
{
Thread.sleep (SLEEPMILLIS);
}
catch (InterruptedException e)
{
System.err.println ("Thread was interrupted.");
}
}
}
public void stop ()
{
// Tell the line-drawing thread to terminate.
runner = null;
}
// The following method is overridden to prevent the drawing surface from
// being automatically cleared after a line is drawn. Stay tuned to Java
// 101 to learn more about this method.
public void update (Graphics g)
{
paint (g);
}
public static void main (String [] args)
{
Frame frame = new Frame ("Lines as an Application");
l = new Lines ();
// NOTE:
//
// It is not necessary to specify frame.add (new Panel ().add (l));.
frame.add (l);
// Create the frame's peer. Peer is not visible. This is necessary
// for when a background buffer must be created in the init() method
// (e.g., Image bk = createImage (100, 100);).
frame.addNotify ();
l.setStub (s = new Stub (args));
frame.setSize (300, 300);
frame.setVisible (true);
// NOTES:
//
// 1) l.init (); must follow frame.setVisible (true); or graphics
// do not display.
//
// 2) The l.doLayout (); call is included in case GUI components
// will be added to applet's panel -- because frame window has
// already been laid out.
l.init ();
l.doLayout ();
s.setActive (true);
l.start ();
frame.addWindowListener (new WindowAdapter ()
{
public void windowClosing
(WindowEvent w)
{
s.setActive (false);
l.stop ();
l.destroy ();
System.exit (0);
}
});
}
}
/* The Stub class provides a mechanism for obtaining information from
the runtime environment. Typically, this environment is maintained
by a Web browser. For this program, a Web browser environment is
being simulated. */
class Stub implements AppletStub
{
private boolean active = false;
private Hashtable ht = new Hashtable ();
private Context c;
// Create a new Stub object. The application's array of command
// arguments are passed to this constructor, where they are saved
// in a Hashtable object for later retrieval by the getParameter()
// method.
Stub (String [] args)
{
c = new Context (); // Create an applet context.
// Make sure an even number of arguments has been passed.
if ((args.length & 1) != 0)
return;
for (int i = 0; i < args.length; i += 2)
ht.put (args [i], args [i + 1]);
}
// Return the current state of an applet. During initialization,
// the applet is not active (and this method returns false). The
// applet's active state is set to true just before the start
// method is called.
public boolean isActive ()
{
return active;
}
// Return the complete URL of the HTML document containing the
// applet. This URL includes the name of the document's file.
public URL getDocumentBase ()
{
URL u = null;
try
{
u = new URL ("file:///" + (new File ("").getAbsolutePath ()) +
"/x.html"); // Use a fake document.
}
catch (MalformedURLException e) {}
return u;
}
// Return the complete URL of the applet's .class file(s). This
// method is often used with the getImage and getAudioClip
// methods to load image/audio files relative to the .class files.
public URL getCodeBase ()
{
URL u = null;
try
{
u = new URL ("file:///" + new File ("").getAbsolutePath () + "/");
}
catch (MalformedURLException e) {}
return u;
}
// Return the value of the applet parameter, identified by the
// name argument. If not present, null is returned. The Applet
// class contains a getParameter() method that calls this method.
public String getParameter (String name)
{
return (String) ht.get (name);
}
// Return a reference to the applet's context. The Applet class
// contains a getAppletContext() method that calls this method.
public AppletContext getAppletContext ()
{
return c; // Return current applet context.
}
// Resize the applet. The Applet class contains a pair of resize
// methods that call this method. Note: Web browsers like Netscape
// don't allow applets to be resized.
public void appletResize (int width, int height)
{
}
// The following method is an extra method that is called to set
// the value of the private active variable.
public void setActive (boolean active)
{
this.active = active;
}
}
/* The Context class provides a mechanism to control the environment
in which the program is running. Typically, this environment is
maintained by a Web browser. For this program, a Web browser
environment is being simulated. */
class Context implements AppletContext
{
// Load the file located by the url argument. The Applet
// class contains a pair of getAudioClip() methods that call
// this method.
public AudioClip getAudioClip (URL url)
{
return Applet.newAudioClip (url);
}
// Prepare to load the image located by the url argument. The
// image is loaded when needed (by one of Graphics' drawImage()
// methods). The Applet class contains a pair of getImage()
// methods that call this method.
public Image getImage (URL url)
{
Toolkit tk = Toolkit.getDefaultToolkit ();
return tk.getImage (url);
}
// Fetch the Applet (identified by name) from the current HTML
// document.
public Applet getApplet (String name)
{
return null;
}
// Return an enumeration to all Applets located on the current HTML
// page.
public Enumeration getApplets ()
{
return null;
}
// Show the HTML document, located by the url argument, in the
// current Web browser window.
public void showDocument (URL url)
{
System.out.println ("Showing document " + url);
}
// Show the HTML document, located by the url argument, in the
// Web browser window, identified by the frame argument.
public void showDocument (URL url, String frame)
{
try
{
showDocument (new URL (url.toString () + frame));
}
catch (MalformedURLException e) {}
}
// Show a status message, identified by the message argument, in
// the Web browser's status bar. The Applet class contains a
// showStatus() method that calls this method.
public void showStatus (String message)
{
System.out.println (message);
}
// The following three methods are required by SDK 1.4. To learn
// about those methods, please refer to the SDK 1.4 documentation.
public InputStream getStream (String key)
{
return null;
}
public Iterator getStreamKeys ()
{
return null;
}
public void setStream (String key, InputStream stream)
{
}
}
I won't bother exploring Lines.java's source code because of the extensive comments. Furthermore, I explore concepts such as streams in future articles. Compile
that source code and run the resulting Lines.class classfile from a command line (via java Lines). Expect to see output similar to what you saw earlier in this series.