Graphics in Java CSE470 Fall 1998 Thanks to Aaron Malenfant for providing the original slides. The slides have been slightly modified to be used in CSE470. Fall 1998 CSE 470 1 Simple Windowing • Frame – A frame provides a Window (through the Window class) with a title bar, menubar, and border. – Inheritence Tree java.lang.Object | +----java.awt.Component | +----java.awt.Container | +----java.awt.Window | +----java.awt.Frame Fall 1998 CSE 470 2 Each Class in the Tree • java.lang.Object – Everything non-basic type is inherited from Object • java.awt.Component – A part of a window from a scrollbar and button to the entire window • java.awt.Container – A container is a component that can contain other components. • java.awt.Window – A Window bas no border or menubars. It is used for pop-up windows. Fall 1998 CSE 470 3 Simple Frame Example import java.awt.*; public class cse470 extends Frame { Label label1; // A simple Component public cse470() { super("Frame Title"); setLayout(new FlowLayout()); resize(300, 300); //Size the window to 300,300 label1 = new Label("Simple Frame"); add(label1); //Add the component show(); //Show the frame } public static void main(String args[]) { new cse470(); } Fall 1998 CSE 470 4 Frame Example Continued public boolean handleEvent(Event event) { if (event.id == Event.WINDOW_DESTROY) { EndApp(); } return super.handleEvent(event); } public void EndApp() { hide(); // hide the Frame dispose(); // tell windowing system to free resources System.exit(0); // exit } } Fall 1998 CSE 470 5 Simple Components • • • • Button CheckBox Label Choice – Drop-down menu • List – Selectable list • Scrollbar • TextArea – An area which a user can enter text. Has both rows and columns. • TextField – A field which a user can enter text. Only has columns. Fall 1998 CSE 470 6 Using a simple component • Declare the object – Button Send; • Create a new instance of the object – Send = new Button(“Send”); • “add” the object to the Frame (or container) – add(Send); • handle the event (in action(Event e, Object arg); ) – if(e.target == Send) { do_something; } Fall 1998 CSE 470 7 Events and Actions • Some components that generate action events : Button • arg = a String with the text label of the button. – Checkbox • arg = a Boolean value which is true if the checkbox is checked. – TextField • arg = a String representing the text in the field – Choice • arg = a String that represents the selected text in the choice Fall 1998 CSE 470 8 Complex component • Canvas • Containers – Frame – Panel – Dialog – Window – Applet • Complex components must be “extend”ed. Fall 1998 CSE 470 9 Using a complex component • Create a new class and source file import java.awt.*; public class MainPanel extends Panel { public MainPanel() { super(); setLayout(new FlowLayout()); label1=new Label("MainPanel", Label.CENTER); add(label1); } public boolean handleEvent(Event event) { return super.handleEvent(event); } Label label1; } Fall 1998 CSE 470 10 Using a complex component, contd. • In the main class, use the new class just like the other components. – Declare the object • MainPanel mp; – Create a new instance of the object • mp = new MainPanel(); – “add” the object to the Frame (or container) • add(mp); Fall 1998 CSE 470 11 Layouts • Layouts automatically arrange the components in a container. • The default is the GridLayout. • To add a component to a container with the GridLayout: – add(String pos, Component ToBeAdded); • The pos can be – – – – – Fall 1998 “North” “South” “East” “West” “Center” CSE 470 12 BorderLayout Fall 1998 CSE 470 13 Code for GridLayout example import java.awt.*; public class BorderTest extends Frame { public BorderTest() { super("BorderTest"); resize(300, 300); add("Center", new Label("Center",Label.CENTER)); add("North", new Label("North", Label.CENTER)); add("South", new Label("South", Label.CENTER)); add("West", new Label("West", Label.CENTER)); add("East", new Label("East", Label.CENTER)); show(); } } Fall 1998 CSE 470 14 Containers within Containers • One of the benifits of a Container is that other containers can be inside a container. Buttonbar Panel Other Sidebar Panel Sidebar Panel Statusbar Panel Fall 1998 CSE 470 15 Canvas • • • • Canvas is a complex component. It is NOT a container You can draw in the Canvas While you can draw in any complex component, you should only do it in a canvas. • Anytime the canvas is redrawn, the paint method is called to redraw it. • Overload the paint method. – void paint(Graphics g) { } Fall 1998 CSE 470 16 Graphics object • Allows an application to draw onto a component. • Some of the information contained in the graphics object is: – The Component to draw on – The current color – The current font Fall 1998 CSE 470 17 Some methods in Graphics • • • • • • • • drawLine(int x1, int y1, int x2, int y2) – Draws a line between the coordinates (x1,y1) and (x2,y2). drawOval(int x, int y, int width, int height) drawRect(int x, int y, int width, int height) drawString(String, int, int) getColor() – Gets the current color. getFont() – Gets the current font. setColor(Color) – Sets the current color to the specified color. setFont(Font) – Sets the current font to the specified font. Fall 1998 CSE 470 18 Canvas Example – Simple.java -- The Frame BoxCanvas n,s,e,w,c; public Simple() { super("Simple App"); resize(300, 300); n = new BoxCanvas(); e = new BoxCanvas(); c = new BoxCanvas(); n.resize(0, 50); w.resize(50,0); add("South", s); add("Center", c); add("West", w); show(); } Fall 1998 s = new BoxCanvas(); w = new BoxCanvas(); s.resize(0, 50); e.resize(50,0); add("North", n); add("East", e); CSE 470 19 Canvas Example -- BoxCanvas.java import java.awt.*; class BoxCanvas extends Canvas { public void paint(Graphics g) { g.drawRect(0,0, size().width - 1, size().height - 1); g.drawOval(0,0, size().width - 1, size().height - 1); } } – size() returns a rectangle with the size of the component. – A Rectangle has a height, width, x, and y. Fall 1998 CSE 470 20 Output Fall 1998 CSE 470 21 Java Applet Basics Fall 1998 CSE 470 22 Converting an application to an Applet • Make an HTML page with the APPLET tag • Remove the main method, move any code from main to “init” • Width and Height must be specified in the HTML page • Derive from Applet instead of Frame • Replace the constructor with init • If the application implicitly uses a border layout, it must be explicit – setLayout(new BorderLayout()); Fall 1998 CSE 470 23 Applet Methods • Methods to override – public void init() • Called by the browser or applet viewer to inform this applet that it has been loaded into the system. • All your GUI initialization should go here. All components should be added here, layouts should be set here. – public void start() • Called by the browser or applet viewer to inform this applet that it should (re)start its execution. • If the browser leaves the page and returns, the start method will be called. The init method will not be called again and all data values will be left intact. Fall 1998 CSE 470 24 More Methods to override – public void stop() • Called by the browser or applet viewer to inform this applet that it should stop its execution. • This happens when the browser leaves the page. The applet is not destroyed, it should just stop running. – public void destroy() • Called when the applet is destroyed. This is the last method called in the Applet. – public String getAppletInfo() • Returns information about this applet. An applet should override this method to return a String containing information about the author, version, and copyright of the applet. Fall 1998 CSE 470 25 Callable Methods • Callable Methods – public boolean isActive() • Determines if this applet is active. An applet is marked active just before its start method is called. It becomes inactive immediately after its stop method is called. – public void resize(int width, int height) – public void resize(Dimension d) • Requests that this applet be resized. – public void showStatus(String msg) • Requests that the argument string be displayed in the "status window". Many browsers and applet viewers provide such a window, where the application can inform users of its current state. Fall 1998 CSE 470 26 Document Location – public URL getDocumentBase() • Gets the document URL. This is the URL of the document in which the applet is embedded. – public URL getCodeBase() • Gets the base URL. This is the URL of the applet itself. – URL • Contains protocal, port, hostname, and file. • Usually passed to other methods • URL is in java.net.URL so it must be imported. Fall 1998 CSE 470 27 Paramaters – public String getParameter(String name) • Returns the value of the named parameter in the HTML tag. • To use paramaters, define them in your HTML file <applet code="Applet1" width=300 height=300> <param name=Owner value=”CSE470"> </applet> • Then a call to getParameter("Owner") returns the value “CSE470”. • The name argument is case insensitive. Fall 1998 CSE 470 28 AppletContext – public AppletContext getAppletContext() • Determines this applet's context, which allows the applet to query and affect the environment in which it runs. • This environment of an applet represents the document that contains the applet. • You can use the AppletContext to load other pages URL u = new URL( “http://www.cps.msu.edu/~cps470”) getAppletContext().showDocument(u); • or for a new window getAppletContext().showDocument(u, “_blank”); • The second parameter could be the name of a frame. Fall 1998 CSE 470 29 Images – public Image getImage(URL url) • Returns an Image object that can then be painted on the screen. The url that is passed as an argument must specify an absolute URL. – public Image getImage(URL url, String name) • Returns an Image object that can then be painted on the screen. The url argument must specify an absolute URL. • The name argument is a specifier that is relative to the url argument. – This method always returns immediately, whether or not the image exists. When this applet attempts to draw the image on the screen, the data will be loaded. The graphics primitives that draw the image will incrementally paint on the screen. Fall 1998 CSE 470 30 More Images • Displaying Images – Graphics Class • public abstract boolean drawImage(Image img, int x, int y, ImageObserver observer) • public abstract boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) – Draws as much of the specified image as is currently available at the specified coordinate (x, y). This method will return immediately in all cases, even if the entire image has not yet been scaled, dithered and converted for the current output device. If the current output representation is not yet complete then the method will return false and the indicated ImageObserver object will be notified as the conversion process progresses. Fall 1998 CSE 470 31 Events in Java 1.0.2 Fall 1998 CSE 470 32 Simple Action Event import java.awt.*; import java.applet.*; public class SimpleEvent extends Applet { Button button1 = new Button("Press me"); public void init() { this.add(button1); } public boolean action(Event e, Object obj) { if(e.target == button1) { button1.setLabel("Again"); return true; } return super.action(e, obj); } } Fall 1998 CSE 470 33 Handling Events • While event handling could be done in handleEvent, it is best to use the convenience functions defined by java. • action(Event evt, Object arg); – All action events such as buttons being pressed, Checkboxes being checked are sent here. – The Object (arg) will be set to one of the following based the component that created the action event (evt.target) • • • • Fall 1998 Button arg is a String with the text label of the button. Checkbox arg is a Boolean value -- the state of the checkbox. TextField arg is a String representing the text in the field Choice arg is a String that represents the selected text in the choice CSE 470 34 Example -- TextTest.java import java.awt.*; import java.applet.*; public class TextTest extends Applet { private TextField hourField = new TextField("12", 3); private TextField minuteField = new TextField("00", 3); private ClockCanvas clock = new ClockCanvas(); private Panel p = new Panel(); private Button tick = new Button("Tick"); private Button set = new Button("Set time"); Fall 1998 CSE 470 35 Example -- Init method public void init() { setLayout(new BorderLayout()); p.setLayout(new FlowLayout()); p.add(tick); p.add(set); p.add(hourField); p.add(minuteField); add("South", p); add("Center", clock); } Fall 1998 CSE 470 36 Example -- action Method public boolean action(Event evt, Object arg) { if (arg.equals("Tick")) clock.tick(); else if (arg.equals("Set time")) { int hours = Integer.parseInt(hourField.getText()); int minutes = Integer.parseInt(minuteField.getText()); clock.setTime(hours, minutes); } else return super.action(evt, arg); return true; } } Fall 1998 CSE 470 37 Example -- ClockCanvs.java import java.awt.*; class ClockCanvas extends Canvas { int minutes = 0; public int getSmaller() { if(size().width < size().height) { return size().width / 2; } else { return size().height / 2; } } Fall 1998 CSE 470 38 Example -- paint public void paint(Graphics g) { int sm = getSmaller(); g.drawOval(0, 0, 2*sm - 1, 2*sm - 1); double hourAngle = 2 * Math.PI * (minutes - 3 * 60) / (12 * 60); double minuteAngle = 2 * Math.PI * (minutes - 15) / 60; g.drawLine(sm, sm, sm + (int)(sm /2.0 * Math.cos(hourAngle)), sm + (int)(sm /2.0 * Math.sin(hourAngle))); g.drawLine(sm, sm, sm + (int)(sm / 1.1 * Math.cos(minuteAngle)), sm + (int)(sm / 1.1 * Math.sin(minuteAngle))); } Fall 1998 CSE 470 39 Example -- other methods public void reset() { minutes = 0; repaint(); } public void tick() { minutes++; repaint(); } public void setTime(int h, int m) { minutes = h * 60 + m; repaint(); } } Fall 1998 CSE 470 40 Mouse Events • mouseDown(Event evt, int x, int y); – Called when the mouse button is clicked • mouseDrag(Event evt, int x, int y); – Called when the mouse moves with the mouse button depressed • mouseUp(Event evt, int x, int y); – Called when the mouse button is released Fall 1998 CSE 470 41 More Mouse Events • mouseMove(Event evt, int x, int y); – Called when the mouse moves with no mouse button depressed • mouseEnter(Event evt, int x, int y); – Called when the mouse enters the component • mouseExit(Event evt, int x, int y); – Called when the mouse leaves the component Fall 1998 CSE 470 42 Example import java.awt.*; import java.applet.*; import java.util.Vector; public class cse470 extends Applet { Vector down = new Vector(); Vector up = new Vector(); public void init() { super.init(); } Fall 1998 CSE 470 43 Example -- mouse events public boolean mouseDown(Event evt, int x, int y) { down.addElement(new Point(x,y)); repaint(); return true; } public boolean mouseUp(Event evt, int x, int y) { up.addElement(new Point(x,y)); repaint(); return true; } Fall 1998 CSE 470 44 Example -- paint public void paint(Graphics g) { Point c; g.setColor(Color.red); for(int i = 0 ; i < down.size();i++) { c = (Point) down.elementAt(i); g.drawOval(c.x, c.y, 2, 2); } g.setColor(Color.blue); for(int i = 0 ; i < up.size();i++) { c = (Point) up.elementAt(i); g.drawOval(c.x, c.y, 2, 2); } } } Fall 1998 CSE 470 45 Exceptions Fall 1998 CSE 470 46 What is an Exception? • An exception is an event that occurs that disrupts the flow of execution. • An exception could be an array out of bounds, File not Found, etc. • A programmer can create their own exceptions. Fall 1998 CSE 470 47 Examine the following Code public class cse470 { public static void main(String args[]) { int i = Integer.parseInt("Not an Integer"); System.out.println("End of Program"); } } – The output is • java.lang.NumberFormatException: Not an Integer – not • End of Program – parseInt threw an Exception Fall 1998 CSE 470 48 Runtime Exceptions • Runtime exceptions are generally caused by programmers. • Runtime exceptions do not have to be explicitely handled. – Integer.parseInt(“Not an Integer”) throws the Runtime Exception NumberFormatException • Non-runtime exceptions must be caught. – MalformedURLException Fall 1998 CSE 470 49 Handling Exceptions • To handle an exception, use a “try” block. int i; try { i = Integer.parseInt("Not an Integer"); } catch (NumberFormatException nfe) { System.err.println("parseInt only works with numbers!"); } • If a NumberFormatException occurs, the catch block will be executed, otherwise the program will continue. Fall 1998 CSE 470 50 Basic Form • The basic form of exception handling is as follows: try { SomethingThat could Throw an Exception; SomethingThat could Throw an Exception; … } catch (SomeTypeOfException somevar) { handleTheException; } catch (SomeOtherTypeOfException somevar) { handleTheException; } Fall 1998 CSE 470 51 The Exception class • String getMessage() – Returns the detail message of this exception object. • void printStackTrace() – Prints this Exception and its backtrace to the standard error stream. • String toString() – Returns a short description of this throwable object. Fall 1998 CSE 470 52 Using the members of the Exception class try { … } catch (Exception e) { System.out.println(“Exception “ + e.getMessage() + “ occurred in MyClass.MyMethod “); e.printStackTrace(); } – or } catch (Exception e) { System.out.println(“Exception “ + e + “ occurred”); } – e alone calls e.toString() to output the class e Fall 1998 CSE 470 53 Example public class cse470 { public static void main(String args[]) { int i = -1; try { i = SomeMethod(); } catch (NumberFormatException nfe) { System.err.println("Exception " + nfe.getMessage() + " occurred"); nfe.printStackTrace(); } System.out.println("End of Program, i = " + i); public static int SomeMethod() { int i = Integer.parseInt("Not an Integer"); return i * 2; } } Fall 1998 CSE 470 54 Output • Exception Not an Integer occurred • java.lang.NumberFormatException: Not an Integer • End of Program, i = -1 Fall 1998 CSE 470 55 Finally block • The finally block is used at the end of a try…catch block. • The finally block will always be executed even if there is an unhandled exception or no exception try { something } catch (Exception e) { ... } finally { clean up code } Fall 1998 CSE 470 56 Example import java.awt.*; import java.applet.*; import java.io.*; public class ExcepTest extends Applet { public void init() { super.init(); setLayout(new GridLayout(2,1)); Panel p = new Panel(); p.setLayout(new GridLayout(4, 2)); add(p); add(tArea); Fall 1998 CSE 470 57 Example contd. CheckboxGroup g = new CheckboxGroup(); p.add(new Checkbox("Divide by zero", g, false)); p.add(new Checkbox("Bad cast", g, false)); p.add(new Checkbox("Array bounds", g, false)); p.add(new Checkbox("Null pointer", g, false)); p.add(new Checkbox("sqrt(-1)", g, false)); p.add(new Checkbox("Overflow", g, false)); p.add(new Checkbox("No such file", g, false)); p.add(new Checkbox("Throw unknown", g, false)); } Fall 1998 CSE 470 58 Example -- action public boolean action(Event evt, Object arg) { try { if (evt.target instanceof Checkbox) { String name = ((Checkbox)evt.target).getLabel(); if (name.equals("Divide by zero")) { a[1] = a[2] / (a[3] - a[3]); } else if (name.equals("Bad cast")) { f = (Frame)arg; } else if (name.equals("Array bounds")) { a[1] = a[10]; } else if (name.equals("Null pointer")) { f = null; f.resize(200, 200); } else if (name.equals("sqrt(-1)")) { a[1] = Math.sqrt(-1); Fall 1998 CSE 470 59 Example -- action contd. } else if (name.equals("Overflow")) { a[1] = 1000 * 1000 * 1000 * 1000; int n = (int)a[1]; } else if (name.equals("No such file")) { FileInputStream is = new FileInputStream(name); } else if (name.equals("Throw unknown")) { throw new UnknownError(); } } else return super.action(evt, arg); } catch(RuntimeException e) { tArea.append("Caught RuntimeException: " + e + "\n"); } catch(Exception e) { tArea.append("Caught Exception: " + e + "\n"); Fall 1998 CSE 470 60 Example -- action contd. } finally { tArea.append("In Finally for " + ((Checkbox)evt.target).getLabel() + "\n"); } return true; } private double[] a = new double[10]; private Frame f = null; TextArea tArea = new TextArea(); } Fall 1998 CSE 470 61 Throwing your own exceptions • your method must be declared to “throw Exception” – public MyMethod throws IOException – public MyMethod throws Exception – public MyMethod throws MyExeception • Then you “throw” the exception – throw new Exception(“Bad Input”); – throw new MyException(“Incorrect Parameter”); Fall 1998 CSE 470 62 Example public class MyClass { public double FourthRoot(double x) throws Exception { if ( x < 0) { throw new Exception(“X must be positive”); } return Math.sqrt(Math.sqrt(x)); } public void MyMethod() { try { FourthRoot(2); FourthRoot(-1); FourthRoot(3); } catch (Exception e) { e.printStackTrace(); } } } Fall 1998 CSE 470 63 Creating your own Exception types • Your Exception class must be extended from Exception (or a child of Exception) public MyException extends Exception { public MyNextException extends MyException { • In the method public MyClass throws MyException { public BadMethod { throw new MyNextException(); } Fall 1998 CSE 470 64 Using custom Exceptions • In the calling program MyClass mc = new MyClass(); try { mc.BadMethod() } catch (MyException e) { do_something; } – MyException includes MyException and MyNextException since MyNextException is a child of MyException. Fall 1998 CSE 470 65