180 likes | 300 Views
GUI Tutorial. Images. Images. Useful Info – not on final exam. Images and Icons. Image class Abstract class – why? Superclass of all graphical image classes Icon interface Represents a fixed-sized picture Methods getIconHeight, getIconWidth, paintIcon
E N D
GUI Tutorial Images
Images Useful Info – not on final exam
Images and Icons • Image class • Abstract class – why? • Superclass of all graphical image classes • Icon interface • Represents a fixed-sized picture • Methods getIconHeight, getIconWidth, paintIcon • Can be used to decorate buttons, labels, tabbed panes • ImageIcon class • Implementation of the Icon interface • Creates an icon from a GIF, JPEG, or PNG image. *
Where’s the image? • Common issue: Eclipse must be able to find the images • For compatibility with jar files, store under src • How can Eclipse find the image? • Create images folder under the [Project]/src • Drag your file into Eclipse (DO NOT just copy in Windows, Eclipse won’t know about it.)
Need to find the image URL url = getClass().getResource("/images/sm_crazybird.gif"); • URL = uniform resource locator • getClass() returns a Class object. Stores details about the class, such as methods, fields etc. • getResource(String) finds a resource with a given name. First creates absolute name of resource. If the String begins with ‘/’, absolute name is String (minus the ‘/’). Otherwise, the package name is appended to the front. In the package name, . are converted to ‘/’ (e.g. package one.two.three would be one/two/three. Important in order to match directory structure. • Toolkit - abstract superclass of all actual implementations of the Abstract Window Toolkit. Subclasses of Toolkit are used to bind the various components to particular native toolkit implementations. • Toolkit.getDefaultToolkit() – gets appropriate toolkit for this platform • Toolkit.getDefaultToolkit().getImage(url) – reads gif, png or jpg pixel data, creates an Image
Potential Issue • Images have to be loaded from disk, can take time • Might have code to draw image on JPanel, but image isn’t loaded when app displays • Solution: MediaTracker • Create a MediaTracker object • Add image(s) • Wait for image(s) to load • Must use try/catch, in case process is interrupted
Put it in code public class ImagePanel extends JPanel { private Image thumbnail; public ImagePanel() { MediaTracker tracker = new MediaTracker(this); URL url = getClass().getResource("/images/crazy_cat.gif"); Image original = Toolkit.getDefaultToolkit().getImage(url); tracker.addImage(original, 0); try { tracker.waitForID(0); } catch (InterruptedException e) { return; } thumbnail = original.getScaledInstance(64, 64, Image.SCALE_FAST); } public void paintComponent(Graphics g) { int PADDING = 20; g.drawImage(thumbnail, PADDING, PADDING, 64, 64, null); } } CHANGE image name as needed
Images and Buttons public class ButtonPanel extends JPanel { private JButton myButton; private ImageIcon myImage; public ButtonPanel() { myButton = new JButton(); URL url = getClass().getResource("/images/crazycat.gif"); myImage = new ImageIcon(Toolkit.getDefaultToolkit().getImage(url)); myButton.setIcon(myImage); add(myButton); } }
Put it all together public class ImageFrame extends JFrame { public ImageFrame() { setTitle("Image Play"); setSize(180, 250); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); ImagePanel imagePanel = new ImagePanel(); add(imagePanel, BorderLayout.CENTER); ButtonPanel buttonPanel = new ButtonPanel(); add(buttonPanel, BorderLayout.SOUTH); } public static void main(String[] args) { // Puts GUI on regular event queue, will update as soon as possible SwingUtilities.invokeLater(new Runnable() { public void run() { ImageFrame frame = new ImageFrame(); frame.setVisible(true); } }); } }
Quick Info: Threads • Threads are covered in detail in CSCI400 and CSCI442 • For now, it’s good to know that there are potentially 3 threads: • Initial threads, the threads that execute initial application code. The main method runs in this thread • The event dispatch thread, where all event-handling code is executed. Most code that interacts with the Swing framework must also execute on this thread. • Worker threads, also known as background threads, where time-consuming background tasks are executed. We won’t deal with these. http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html
Correct way to start a GUI public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { ImageFrame frame = new ImageFrame(); frame.setVisible(true); } }); } http://javarevisited.blogspot.com/2011/09/invokeandwait-invokelater-swing-example.html http://www.javamex.com/tutorials/threads/invokelater.shtml http://www2.sys-con.com/itsg/virtualcd/Java/archives/0605/ford/index.html
More Images Draw on a panel, MediaTracker
MediaTracker • Images that are created from a URL, filename or byte array are preloaded using MediaTracker to monitor the loaded state of the image.
You can also draw images import javax.swing.*; import java.net.*; import java.awt.*; public class ImagePanel extends JPanel { private Image original; private MediaTracker tracker; public static final int PADDING = 20; public ImagePanel() { tracker = new MediaTracker(this); original = getImage("/images/crazycat.gif"); tracker.addImage(original, 0); try { tracker.waitForID(0); } catch (InterruptedException e) { return; } } Use MediaTracker to control timing – without this, the panel may display before the image is loaded.
Drawing images, continued public void paintComponent(Graphics g) { g.drawImage(original, PADDING, PADDING, 64, 64, null); } private Image getImage(String pathName) { URL url = getClass().getResource(pathName); Image image = Toolkit.getDefaultToolkit().getImage(url); return image; } public static void main(String[] args) { JFrame frame = new JFrame("Image Play"); ImagePanel panel = new ImagePanel(); frame.add(panel); frame.setSize(200, 200); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }
Advanced Topics Image in a jar
Jar File • In Eclipse, highlight project • Right-click, Export, Jar. • Pick location for jar file • On the last dialog, identify the class containing main
Complete program for reference - Image import java.awt.*; import javax.swing.*; import java.net.*; public class ImageGUI extends JPanel { private ImageIcon myImage; public ImageGUI() { JButton button = new JButton(); add(button); myImage = new ImageIcon(getImage("/images/crazycat.gif")); Image original = myImage.getImage(); button.setIcon(myImage); } public Image getImage(String pathName) { URL url = getClass().getResource(pathName); Image image = Toolkit.getDefaultToolkit().getImage(url); return image; } public static void main(String[] args) { JFrame frame = new JFrame("Image Play"); ImageGUI panel = new ImageGUI(); frame.add(panel, BorderLayout.CENTER); frame.setSize(200, 200); frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } } // end of class