410 likes | 600 Views
EE2E1. JAVA Programming. Lecture 5 Graphics programming and Swing. Contents. Overview of graphics in Java – AWT & Swing Frames Swing inheritance hierarchy Displaying graphics in frames – panels Displaying text in graphics windows Drawing simple graphics Displaying images.
E N D
EE2E1. JAVA Programming Lecture 5 Graphics programming and Swing
Contents • Overview of graphics in Java – AWT & Swing • Frames • Swing inheritance hierarchy • Displaying graphics in frames – panels • Displaying text in graphics windows • Drawing simple graphics • Displaying images
Overview of graphics in Java – AWT & Swing • Most modern application programs use sophisticated graphics and have powerful graphical user interfaces • Spreadsheets • Word processing • Web browsers • Email programs • Its important to extend our knowledge from writing crude console-based programs to portable graphical applications
Java, unlike C & C++, has standard packages for graphics • 2 related packages and sub-packages support graphics in Java • java.awt (Abstract Windows Toolkit) • javax.swing • AWT is ‘peer-based’ • Depends on graphical elements native local platform’s graphics system • Unix/Windows graphical programs written using AWT will have a different ‘look and feel’
Swing is much more platform independent • Graphical components are pre-built and are simply painted onto windows • Relies less on the underlying runtime environment • Usually slower than AWT-based programs • In practice graphical programs are a mixture of Swing and AWT classes • AWT takes care of all of the event handling for GUI’s (see later)
Frames • A frame is a top level window which is a container for graphical components (canvas, buttons, menus etc) • The AWT has a Frame class and Swing has a JFrame class • The following program displays an empty frame
import javax.swing.*; class MyFrame extends JFrame { public MyFrame() { setTitle("My first graphics program"); setSize(400,300); } } public class FrameTest { public static void main(String[] args) { JFrame frame=new MyFrame(); frame.setVisible(true); } }
A class MyFrame is defined which is a sub-class of JFrame • A title is added • The frame is sized to 400x300 (by default, a frame is 0x0) • The frame is created by a call to the constructor • The frame is displayed by a call to JFrame.setVisible(true) • This creates a separate thread which runs until the program is terminated – the main thread terminates
A closeable frame • The above program cannot be terminated by clicking ‘Quit’ (or the ‘x’ in the top right hand corner of the MS-window) – the window is hidden but the thread continues • Need to send an event to the window to tell it to close • Event handling is relatively complex in Java (see next lecture) • We add a WindowListener to the frame which listens for events generated in windows
We create an object of the WindowListener interface by implementing all of it methods • There are 7 methods to implement • The only one we need is the windowClosing method • AWT provides a WindowAdapter class which implements all 7 methods – we simply need to extend it providing our own implementation of windowClosing
class MyWindowListener extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } }
We could then call addWindowListener() in the constructor which creates the closeable frame • addWindowListener() is passed an unreferenced MyWindowListener object class MyCloseableFrame extends JFrame { public MyCloseableFrame() { . . addWindowListener(new MyWindowListener()); } }
We can make this even more succint by creating an anonymous class which avoids having to give a name to the MyWindowListener class • We know the class is extended from WindowAdapter • Makes the code totally incomprehensible! • Don’t worry about it – just use it as a template for all your closeable frames! • The complete closeable frame class is as follows
import javax.swing.*; import java.awt.event.*; import java.awt.*; class MyCloseableFrame extends JFrame { public MyCloseableFrame() { setTitle("My first closeable frame"); setSize(400,300); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); } }
Swing inheritance hierarchy • The JFrame class inherits attributes from higher level container classes • Typically for resizing and positioning frames • Class names beginning with ‘J’ are Swing classes – everything else is part of AWT
Component Container Window Frame JComponent ….. JPanel JFrame
Most swing components (for example JPanel) are derived from the JComponent class • JFrame, being a top level window, is derived from the Window class • Other top level windows include JApplet and JDialog
Displaying graphics in frames – panels • Frames are containers – they can contain other user interface/graphical components • A frame contains a content pane into which components can be added • The following code is typical Container contentPane=frame.getContentPane(); Component c= ….; // UI or graphical component contentPane.add (c); // Add to the frame
Frame Content pane
Panels • Panels (JPanel class) are added to the content pane • Panels are themselves containers • The can contain other UI components • They also have a surface onto which graphics can be drawn • Text • Basic shapes (lines, boxes etc) • Images
Drawing on panels • The paintComponent() method in JComponent (a superclass of JPanel) must be overridden • paintComponent() is called automatically when the window has to be drawn or redrawn – for example when it is moved by the user. It is also called when the repaint() method of a panel is called
The following code creates a class MyPanel into which graphics can be drawn class MyPanel extends JPanel { public void paintComponent(Graphics g) { super.paintComponent(g); // Code placed here to draw graphics } }
The Graphics object defines the graphics context (fonts, line styles, colours etc) • A call to super.paintComponent() calls the paintComponent() method in JComponent (the base class of JPanel) • This call sets up the graphics context and performs other complex tasks
Displaying text in graphics windows • Text can be drawn onto panels using the Graphics.drawString() method • The text font and size can be optionally set/reset • The following program draws a string onto a panel • The panel is then added to a frame which is then displayed using JFrame.setVisible(true)
import javax.swing.*; import java.awt.*; public class MyPanel extends JPanel { public void paintComponent(Graphics g) { super.paintComponent(g); g.drawString("Hello there!",150,125); } }
import java.awt.event.*; import javax.swing.*; import java.awt.*; public class HelloFrame extends JFrame { public HelloFrame() { setTitle("Drawing a string example"); setSize(400,300); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); Container contentPane=getContentPane(); contentPane.add(new MyPanel()); } }
public class FrameTest { public static void main(String[] args) { JFrame frame=new HelloFrame(); frame.setVisible(true); } }
Text fonts can be set/reset • The existing font applies until it is reset • The following code sets a bold Helvetica font with a larger font size public class MyPanel extends JPanel { public void paintComponent(Graphics g) { super.paintComponent(g); Font f=new Font(“Helvetica”,Font.BOLD,25); g.setFont(f); g.drawString("Hello there!",150,125); } }
Drawing simple graphics • Class java.awt.Graphics contains methods which allow simple graphics to be drawn in different colours • Graphics.setcolor() setsthe drawing colour • Colour is represented by the class java.awt.Color(int red, int blue, int green) defining the RGB components • Preset constants exist (defined as static constants in Color) • Color.red • Color.orange • Color.pink • etc
Examples of different shapes • Graphics.drawLine(int x1, int y1, int x2, int y2) draws a straight line from (x1,y1) to (x2,y2) • Graphics.drawRect(int x, int y, int w, int h) draws a rectangle from upper left hand corner (x,y) with width w and height h • Graphics.drawOval(int x, int y, int w, int h) draws an outline of an ellipse with a ‘bounding rectangle’ as above • Graphics.drawPolygon(int[] xc, int[] yc, int n) draws a polygon with n vertices with the co-ordinates being stored in arrays xc and yc • Graphics.fillOval (int x, int y, int w, int h) fills the oval with the current draw colour
class DrawPanel extends JPanel { public void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.red); g.drawRect(20,30,50,50); g.setColor(Color.green); g.drawOval(100,30,90,60); g.fillOval(100,30,90,60); g.setColor(Color.yellow); int[] xcoords={180,200,250,275,225}; int[] ycoords={170,130,130,150,200}; g.drawPolygon(xcoords,ycoords,5); g.fillPolygon(xcoords,ycoords,5); } }
Displaying images • We can read images stored in GIF and JPEG formats and draw the image onto a graphics panel using Graphics.drawImage() • When an image is read from file, a new thread of execution is started in parallel • Usually, the program needs to wait until the image is loaded • Loaded images need to be ‘tracked’ and the program informed when the loading is complete • Java has a MediaTracker class to do this • This approach is especially useful when loading an image over a slow network connection using an applet
Normal program thread Create new thread Load image from file Image loading thread Program waits to be informed when image loaded Image loading complete – send signal Normal program thread resumes
import java.awt.*;import java.awt.event.*;import javax.swing.*;class ImagePanel extends JPanel{public ImagePanel() {image = Toolkit.getDefaultToolkit().getImage(“Pisa.jpg”);MediaTracker tracker=new MediaTracker(this);tracker.addImage(image,0); try {tracker.waitForID(0);} catch (InterruptedException e){} } public void paintComponent(Graphics g) {super.paintComponent(g);g.drawImage(image,0,0,this); }private Image image;}
Image read from file by a Toolkit object • getDefaultToolkit() returns the default toolkit • getDefaultToolkit().getImage(filename) reads the jpg or gif file containing the image • An image is added to a tracker object which sends a signal back to the panel when the loading is complete • The try/catch statements are for exception handling – causes the program to wait for the image to be loaded (see later) • Following program draws an image into a panel
And finally …. • Swing/AWT are massive and complex • We have only scratched the surface • Typically Java API’s have been built on top of Swing • Java2D • Java3D • In practice, you would use these to do real work for example involving image processing or 3D rendering