Java Tutorial, May 14, 1996 Applet Basics: Graphics, threads and animation Some Basic Methods for Applets -- I Some of These are in Applet and some in parent (in particular Component) public void init() is called ONCE and ONCE only when the applet is loaded or reloaded. Set initial parameters etc. here. public void destroy() is what you do when Applet is entirely finished and you need to clean up stray threads or connections to be closed. public void start() is called whenever the applet is started which can happen several times during an applet's life-cycle as it starts each time you revisit a page public void stop() is called when we temporarily leave Applet to visit another page. A wise move would be to suspend running of Threads to save system resources. Some Basic Methods for Applets -- II public void paint(Graphics g) actually has an argument and draws what you want on the screen There is somewhat confusing other methods update() and repaint() which need to used in advanced applications. You may need to call repaint() in a dynamic applet to change display but update() would not need to be called as invoked by repaint(). However update() is sometimes best overridden public void repaint() is a request by you to the Java runtime to update screen public void update(Graphics g) is invoked by repaint() and performs the screen update which involves clearing screen and invoking paint() The details of the tag Put a bunch of text here to be displayed by browsers such as Netscape 2.0 on Windows 3.1 that do not support Java One can also include INSIDE tag, attributes available for tag in conventional HTML. These attributes are Align=texttop which aligns top of applet with top of the tallest text in the line Align=top which aligns top of applet with top of tallest item in the line and align= absmiddle, middle, baseline, bottom, absbottom with similar meaning hspace=num1 allows num1 pixels to either side of applet and surrounding text vspace=num2 allows num2 pixels to top and bottom of applet and surrounding text Tags and Applets can be followed by ....... The Java program accesses this information by String attribute; attribute = getParamter("attributename1"); if( attribute == null ) attribute = yourdefaultvalue; // null is Java way of saying unset Typically this processing would be in init() method of Applet The java.awt.Graphics Class java.awt has several important classes including Graphics, Color, Font and FontMetrics Graphics class has primitives to construct basic two dimensional images with methods drawString (text), drawLine, drawRect, fillRect, drawRoundRect (for a rectangle with rounded corners!), draw3DRect (to get shadow effect as in buttons), drawPolygon (general polygon), drawOval, fillOval There are also Image, Font, Color operations The java.awt.Font and FontMetrics Classes Graphicsinstance.setFont(particularFont) will set the current Font in the instance Graphicsinstance of graphics class to the value particularFont of class Font. There are several other such Font related methods in the Graphics class The class Font has an important constructor used as in Font particularFont = new Font("TimesRoman",Font.PLAIN,36); where one can use Courier Helvetica etc. instead of Time Roman Font.PLAIN, Font.BOLD, Font.ITALIC are possible text styles FontMetrics fm = getFontMetrics(particularFont); // allows one to find out about the font fm.stringWidth("text"); // returns pixel width of string "text" fm.getHeight(); // returns total height of one line of Font The java.awt.Color Classes Color c = new Color (redvalue, greenvalue, bluevalue); // red/green/bluevalue can be specified as integers in 0.....255 or floating point numbers from 0 to 1. c is generated as a Color in RGB format. graphicsobject.setColor(c); // sets current color in graphicsobject which is used for all subsequent operations graphicsobject.setFont(particularFont); // similarily sets font hereafter as on previous page There are particular Color instances already defined such as Color.white equivalent to Color(255,255,255) Color.black as equivalent to Color(0,0,0) Color.pink as equivalent to Color(255,175,175) The default Update(Graphics g) Method This sets background color and initializes applet bounding rectangle to this color public void update(Graphics g) { g.setColor(getBackground()); g.fillRect(0,0,width,height)); g.setColor(getForeground(); paint(g); } getBackground() and getForeground() are methods in component class fillRect() is a method in Graphics class Threads as Discussed in Sun's Tutorial One can implement threads in two ways Firstly subclassing the Thread class and overriding its run() method Secondly by creating a Thread with a Runnable object (i. e. that implements Runnable interface) Only the second way is possible for applets as these already extend Applet class and so cannot multiply inherit from the Thread class Threads must have a run method which is code Thread executes. If you are using first way, this is written for this particular thread and overrides run() in Thread class In second way, the created Thread automatically takes its run() method to be the run method of the applet Sun's Digital Clock Applet to Illustrate Threads -- I import java.awt.Graphics; import java.util.Date; public class Clock extends java.applet.Applet implements Runnable { Thread clockThread; public void start () { if (clockThread == null) { clockThread = new Thread (this, "Clock"); clockThread.start (); } } Sun's Digital Clock Applet to Illustrate Threads -- II public void run () { while (clockThread !=null) { repaint (); try { clockThread.sleep(1000); } catch (InterruptedException e) { } } // end while } // end run() public void paint (Graphics g) { Date now = new Date (); g.drawString (now.getHours() + ":"+ now.getMinutes() + ":"+now.getSeconds(), 5, 10); } public void stop () { clockThread.stop(); clockThread = null; } } // End Digital Clock Applet Flickering in Applets and its Solution Unless you are careful, dynamic applets will give flickering screens This is due to cycle paint(g) update(g) clearing screen paint(g) drawing new screen ..... where flicker caused by rapid clear-paint cycle. There are two ways to solve this problem which involve changing update in different ways 1: Change update() either not to clear screen at all (because you know paint() will write over parts that are to be changed) or to just clear the parts of the screen that are changed or 2:Double Buffering Sun's Animator.class Applet Sun distributes a general purpose Animation applet with the Java Development Kit Advantages: 1. quick: users don't have to write their own program in order to get interesting animation effects. 2. flexibility: user can assign the directory and the file name for the image frame and sound files by using imagesource, soundsource, soundtrack, and sound parameters in applet tag. Disadvantage: 1. Image blinking: This applet fail to use double buffering and one can see serious blinking on screen. 2. Separating the frames into different files makes it easy to program but will slow down the image loading process. Details of Using the Sun animator Applet --I 1. Prepare a directory. and cd to this directory. 2. Copy Animator.class, ParseException.class, and ImageNotFoundException.class into your directory. 3. create a directory audio and put your audio file in it. Your audio files can be called 0.au, 1.au, etc. The background soundtrack could be any .au file. 4. create a directory images and put your image files in it. your image files can be called T1.gif, T2.gif, etc. the loading message can be called loading-msg.gif. 5. prepare a HTML page which has the following type of applet tag: Details of Using the Sun animator Applet --II the imagesource attribute indicate you put your image files in directory images. the endimage value 10 indicate that you have 10 image files held in T1.gif, T2.gif, ..., to T10.gif The soundsource indicate that you put your sound files in audio directory. The sounds attribute lets you express your audio file sequence. the pause attribute is the pause (ms) between each image frame. There are other parameters which can be set such as: This image will show up first to remind user that image is loading. ColorSwirl -- An Example from Teach Yourself Java in 21 Days - I public class ColorSwirl extends java.applet.Applet implements Runnable { Font f= new Font ("TimesRoman", Font.BOLD, 48); Color colors [] = new color [50] Thread runThread; public void start () { if (RunThread == null) { runThread = new Thread (this); runThread.start (); } } ColorSwirl -- An Example from Teach Yourself Java in 21 Days - run Method public void run () { float c = 0; // initialize the color array for (int i = 0; i < colors.length; i++) { colors [i] = Color.getHSBColor (c, (float) 1.0, (float) 1.0); c +=.02; } int i = 0; // cycle through the colors while (true) { setForeground (colors [i]); repaint (); i++; try { Thread.sleep(50); } catch (InterruptedException e) { } if (i == color.length) i = 0; } // End while(true) } // end run() ColorSwirl -- An Example from Teach Yourself Java in 21 Days - paint and update public void stop () { if (runThread != null) { runThread.stop(); runThread = null; } } public void paint(Graphic g) { g.setFont(f); g.drawString ("All the Swirly Colors", 15,50); } public void update(Graphics g) { paint(g); } // No need to clear background as unchanged! -- only color of letters changes } // end Applet ColorSwirl Double Buffering to Reduce Flicker - I Here you have two "graphics contexts" (frame buffers of the size of the applet), and you construct the next image for an animation "off-line" in the second frame buffer. This frame buffer is then directly copied to the main applet Graphics object without clearing image as in default update() Image OffscreenImage; // Place to hold Image Graphics offscreenGraphics; // The second graphics context which contains offscreenImage offscreenImage = createImage(width,height); offscreenGraphics = offscreenImage.getGraphics(); Double Buffering to Reduce Flicker - II The previous statements could be in init() while in paint(), one will construct applet image in offscreenGraphics as opposed to the argument g of paint(). So one would see statements such as: e.g. offscreenGraphics.drawImage(img,10,10,this); Finally at end of paint(), one could transfer the double buffered image to g by g.drawImage(offscreenImage,0,0,this); One would also need to override the update() method by public void update(Graphics g) { paint(g); } Event Handling Events in the java.awt -- Mouse, Keyboard Interaction - I Events ( distinguish these from Exceptions!) are the way the AWT interacts with the user at mouse or keyboard. The AWT calls particular event handlers (analogous to exception or interrupt handlers) when user interacts with system in particular ways. The handling is defined in packages java.awt and java.awt.peer (the machine dependent stuff) with method handleEvent() in class Component(peer) One could add additional capability here for systems with nifty virtual reality and other user interfaces but we won't cover this here! public boolean keyDown(Event evt, int key) { } method is called when you press keyboard. Events in the java.awt -- Mouse, Keyboard Interaction - II The Event class has various special class (static) variables defined including Event.F1 -- the F1 key Event.UP The Up arrow etc. The Component class (grandparent of Applet) has a rich set of Event handlers which you should override if you wish to process particular input public boolean mouseDown(Event evt, int x, int y) { anchor = new Point(x,y); // record position of mouse click return true; // must do this } Other handlers are mouseDrag, mouseEnter (enters current component), mouseExit, mouseMove (with its button up), keyUp, keyDown Abstract Windowing Toolkit (AWT): Layouts and Components such as buttons, textfields, etc. Structure of the java.awt GUI Components - I In Java, the GUI (Graphical User Interface) is built hierarchically in terms of Components -- one Component nested inside another starting with the smallest Buttons, including Menus, TextFields etc. and ending with full Window divided into Frames, MenuBars etc. Not all useful Classes are inherited from Component. For instance Menu inherits from MenuComponent (interface) --> MenuItem --> Menu One also needs a set of methods and classes to define the layout of the Components in a particular Panel LayoutManager is a java.awt interface with several particular layout strategies implemented as classes under this interface The Container class has methods to interact with LayoutManager classes Structure of the java.awt GUI Components - II In the simplest use of AWT, one could add a Button to an Applet (grandchild of Container) using in the init() method for Applet Button b = new Button("Are You Feeling well"); add(b); // add() is a Container method The various added Components are put in the panel by the LayoutManager using order in this they were added A Final critical part of the AWT is the actions generated by these components which are processed by overriding the action() method in Component action(Event e, Object Anyargemightliketoreturn); We define extra events -- such as those connected with scrolling or selecting buttons to those of basic mouse/keyboard Picture of the AWT Component Class and its inheritance This is incomplete! Some Simple AWT Components -- label,button add(new Label("aligned left")); // default alignment produces a text string using constructor Label of Label class add(new Button("Grade is A")); add(new Button("Grade is B")); // surely this is lowest grade for a course on such an easy language? AWT Components -- Checkbox Checkbox's are on-off toggles implemented as add(new Checkbox("Red")); // defaulted to false as initial value which can be changed by user add(new Checkbox("Green")); // defaulted to false add(new Checkbox("Blue"),null, true); // set to true -- second argument required but ignored here AWT Components -- Radio Buttons , CheckboxGroup Radiobuttons are identical to Checkbox's but grouped so that only one in a group can be on at a time. They use same class for buttons but add CheckboxGroup class CheckboxGroup cbg = new CheckboxGroup(); // cbg is group for one set of radiobuttons add(new Checkbox("Red", cbg, false)); // cbg is second argument!! add(new Checkbox("Green", cbg, false)); add(new Checkbox("Blue", cbg, true)); // Only one in group cbg can be true Some Further AWT Components -- typical subunits of panels Choice is a class that gives a menu where you choose from various items TextField is a simple class where user can enter information into fields TextArea is a somewhat more sophisticated text entry area which are scrollable and so useful where amount of data to be entered is unlimited List is another child of Component that is similar in use to Choice but gives a fixed size list which can be scrolled and where you can select one or more entries Scrollbar is a class that defines a horizontal or vertical scrollbar. Note this is distinct from scrollbars that come with TextArea and List Some Further AWT Components -- Canvas, Window - I Canvas is a simple class which are used to draw on as in artist's canvas. They cannot contain other components Upto now, we have described how to build typical Applet panels inside browser window. There are classes that allow one to generate complete windows separately from the browser window Window Class has subclasses Frame and Dialog Frame("TitleofWindow"); // creates a window with memubar and given title Note Frame is a Container and can thereof be defined hierarchically with components that are laid out by LayoutManagers Some Further AWT Components -- Canvas, Window - II MenuBar(); // defines a menubar which can be used in a frame Menu("Type"); // defines a menu which can itself have hierarchically defined submemus Dialog(Frame, String Title, boolean mustbeansweredatonceornot); // defines a dialog box Dialog boxes are used for transient data Issue warning to user or require (third argument true) user to verify some action etc. Actions associated with Components in AWT - I We already discussed handling Mouse and Keyboard Events. These AWT components come with new actions which need to be handled with an action() method in your applet Put action ( a method of class Component) in Container instance that is at lowest possible level so you can customize action to things in that Container action(Event evt, Object arg)'s are looked for in same fashion as exceptions. Scan up Containers looking for a method of this name. Scanning stops when you find an action and that method returns true evt.target holds the object that caused the Event Object Arg returned depends on particular Component invoked There are further evt.id's associated with the various peculiar Components -- see description of class Event for current detailed description. Actions associated with Components in AWT - II Suppose we have a bunch of buttons in a particular Container saying Red, Green, Blue as we illustrated earlier. Then a good action method would be public boolean action(Event evt, Object arg) { if( evt.target instanceof Button) changeColor((String) arg); // changeColor Supplied by the user processes color defined by text string used in defining buttons return true; // tell runtime that this event fully processed } void changeColor(String bname) { // A suitable user routine to be called by above action if( bname.equals("Red")) setBackground(Color.red); else if (bname.equals("Green")) setBackground(Color.green); else if (bname.equals("Blue")) setBackground(Color.blue); else setBackground(Color.pink); // our favorite color } Layout of Components in a Panel The various panels in a container are laid out separately in terms of their subcomponents One can lay components out "by hand" with positioning in pixel space However this is very difficult to make machine independent. Thus one tends to use general strategies which are embodied in 5 LayoutManger's which all implement the LayoutManager Interface. One can expect further custom LayoutManager's to become available on the Web setLayout(new FlowLayout()); // creates a basic flow layout in your panel -- actually unnecessary as default Other available LayoutManager's are GridLayout(), BorderLayout() (default for Frame's), CardLayout() (Used for dynamic layouts) and GridBagLayout() (the most flexible) Description and Example of BorderLayout BorderLayout has five cells called North South East West Center and components are assigned to these cells with the add method. As used in a window, one would naturally use: add("North", new TextField("Title",50)); add("South", new TextField("Usuallyreservedforstatusmessage",50)); Remember this is default for a Frame Container Brief Description of Four Other LayoutManager's FlowLayout is a one dimensional layout where components are "flowed" into panel in order they were defined. When a row is full up, it is wrapped onto next row GridLayout is a two dimensional layout where you define a N by M set of cells and again the components are assigned sequentially to cells starting at top left hand corner -- one component is in each cell GridBagLayout uses a new class GridBagConstraints to customize positioning of individual components in one or more cells CardLayout lays out in time not space and each card (Displayed at one time) can be laid out with one of spatial layout schemes above Hierarchical use of LayoutManagers Layout's can be made very sophisticated using an hierarchical approach setLayout(new GridLayout(1,3,10,5)); // Number of cells in y, Number in x, Horizontal gap, Vertical Gap subpanel1 = new MysubpanelClass(); // Add arguments to make subpanel1 special subpanel2 = new MysubpanelClass(); add(Some Simple Component such as a Button); add(subpanel1); add(subpanel2); .......... Class MysubpanelClass extends panel { // has constructor MysubpanelClass() { // that includes another layout such as setLayout(new GridLayout(7,7,5,5); // etc. Networking, Web Access and I/O Networking, Web Access and I/O in Java This area will evolve rapidly as existing I/O systems get linked to Java with special classes such as those needed to link MPI (HPCC Message Passing) or Nexus (Well known distributed memory thread package) One can establish Web Connection with URL class and access documents there One can set up a more general URLConnection for more general input/output operations through Web(HTTP) protocol One can set up a Socket link which is permanent rather than on again off again Web client-server interaction One can send messages and so transfer information between different Applets One can (outside Netscape) access same functionality as usual UNIX stdio library Accessing URL's in Java -- URL, showDocument First you set the URL in various ways using something like String npacurl = "http://www.npac.syr.edu/index.html"; try { theinputurl = new URL(npacurl); } // URL class is in java.net catch ( MalformedURLException e) { System.out.println("Bad URL: " + npacurl); } where you are meant to test to see if URL is legal! The simplest thing to do now is to see this page with getAppletContext().showDocument(theinputurl, Frame targetdisplayframe); Accessing URL's in Java -- URLConnection More interesting is to access a URL and process the information there! This is done using a stdio like stream (generalizes pipe) which is supported in java.io package with usual buffering capabilities There are methods in class URL -- InputStream in = instanceofURL.openStream(); // opens an InputStream associated with given url More general is instanceofURL.openConnection() establishes a general connection and returns an instance of class URLConnection This provides most general HTTP connectivity and indeed has some advantages over sockets as these are subject to special security restrictions in Netscape's current implementation Note that one can connect not just to HTML files but also to CGI scripts i.e. programs at server and so obtain flexible connectivity Input/Output in Java -- InputStreams -- I In java.io, there are several classes that throw IOExceptions -- please catch them! The class InputStream is basic and it has methods such as read() skip() (bytes in a stream) available() (bytes remaining in stream) close(). InputStreams can be created from memory InputStream s = new ByteArrayInputStream(buffer, 100, 300); // creates a stream of 300 bytes in locations 100 to 399 More usefully, they can be created from a UNIX file InputStream s = new FileInputStream("/usr/gcf/greatidea"); Input/Output in Java -- (Filter etc.)InputStreams -- II There is a clever class called FilterInputStream which can be used to add value to a raw InputStream. You can define your own filters but important ones provided are: BufferedInputStream -- establishs an intermediate buffer to service stream DataInputStream -- allows one to address stream in terms of higher level constructs -- namely read a line, read a long integer etc. LineNumberInputStream -- adds line numbers to a stream PushbackInputStream -- allows one to "unread" a character and put it back on the input stream Accessing URL's in Java -- InputStreams and URLConnections String line; // Here is a useful example try { URLConnection conn = npacurl.openConnection(); conn.connect(); // could set options after creation of conn in above line and before connect method invoked InputStream in = conn.getInputStream(); // establish an InputStream on this connection DataInputStream data = new DataInputStream(new BufferedInputSream(in)); // set up two filters allowing both buffering and line access to InputStream while ((line = data.readline()) != null ) { System.out.println("line"); } // print out line -- obviously put your favorite line processing here } catch (IOException e) { process error } Note one useful exception EOFException which can be caught and remove testing in read loops Performance and the Future Use of Native Classes to Speed Up Execution One can essentially augment supplied Java Runtime by supplying your own C or other code implementing a particular functionality in a higher performance mode This of course generates machine dependence and should only be used if really needed First for classes you wish to implement in native fashion, put in your java code lines like: public native mustgofast(arguments); // default functions static { System.loadLibrary("faststuffhere"); } // static and in class and so runs only ONCE! and loads the native code HPCC and Java -- High Performance HPjava -- I The activities that has gone into defining High Performance Fortran (HPF) and HPC++ can be reexamined for Java which is quite well suited for parallelism as It essentially has task parallelism built in with Applet mechanism As there are no pointers, it is easier to define data and other implicit parallelism so it can be efficiently implemented Interesting Compiler challenge independent of parallelism, is to produce efficient code from bytecodes. Here a technique called "just in time" compilation does compilation at runtime and can probably increase performance of Java code by a factor of 10 or so to become comparable with performance of C Surely many will produce Fortran C PASCAL to Java translators so you can webify your existing applications This is an alternative to wrapper technology as in native classes HPCC and Java -- HPjava -- II Current runtime (java Threads) assume shared memory but there are interesting possible distributed memory and distributed shared memory implementations One can imagine a dataparallel interface where methods would implement array and other data parallel operations with distributions specified by annotations as in HPF Here one has a HPJava translator that produces java "plus message passing" code Important implication for parallel CORBA using Java classes to interface with CORBA Java based servers will allow data and task parallel Java to implement World Wide compute webs