CS212: Summer 2003 Lecture 3 - Graphical User Interfaces ----------------------------------------------------------------------- 0) Announcements Course website and project are up. Check website for important announcements ----------------------------------------------------------------------- 1) Overview of JFC / Swing, and AWT AWT (the Advanced Windowing Toolkit) was the first Java library for creating GUIs. They improved greatly on AWT by creating Swing. JFC is short for Java Foundation Classes, which encompass a group of features to help people build graphical user interfaces (GUIs) Swing is an unofficial name for JFC. Swing components are found in the javax.swing package. Just import javac.swing.* in your programs. Swing components are identified by a capital J in front of the name. For example, AWT defines the Button class, whereas Swing defines the JButton class. Go to http://java.sun.com/docs/books/tutorial/ and click on the "Creating a GUI with JFC/Swing" link for a tutorial. Source: http://java.sun.com/docs/books/tutorial/uiswing/start/swingIntro.html ---------------------------------------------------------------------- 2) Swing components http://java.sun.com/docs/books/tutorial/uiswing/index.html Picture a Swing application with a button and a label. Such an app has four commonly used Swing components: + JFrame - a top-level container - provides a place for other Swing components to paint themselves. - Other examples: JDialog, JApplet + JPanel - intermediate container - helps to position buttons, labels, and other components - other intermediate containers: JScrollPane, JTabbedPane + JButton, JLabel - atomic components (do not hold other Swing components) - give/take information to/from the user - there are many atomic Swing components Containment hierarchy for this simple program: JFrame | ... | JPanel | +-----+-----+ | | JButton JLabel ADDING COMPONENTS TO OTHER COMPONENTS To add a component to a container, we use the container's add() method, whose argument is the component to be added. Thus, to add to a JPanel, we call panel.add(). Adding to a JFrame is a little different. The content pane is the JFrame's container that holds the components in the frame. Thus, if we want to add something to the frame, we call frame.getContentPane().add( ). This is different from adding to a JPanel; note the one extra method call. Here is the code that adds the button and label to the panel, and the panel to the content pane: frame = new JFrame(...); button = new JButton(...); label = new JLabel(...); pane = new JPanel(); pane.add(button); pane.add(label); frame.getContentPane().add(pane, BorderLayout.CENTER); http://java.sun.com/docs/books/tutorial/uiswing/overview/hierarchy.html ----------------------------------------------------------------------- 3) Layout Management LAYOUT MANAGEMENT + "The process of determining the size and position of components." - each component has a layout manager (FlowLayout is usually default) - layout manager performs layout of components in the container - components can provide size and alignment hints, but manager has the ultimate authority + Five commonly used layout managers: 1) BorderLayout: has North, South, East, West, and Center positions 2) BoxLayout: places components from top to bottom - sometimes confusing. Just use the Box object, which is basically a container with a BoxLayout manager 3) FlowLayout: places components left to right 4) GridBagLayout: most complex and flexible - aligns components along grid of cells, allowing for overlap - http://java.sun.com/docs/books/tutorial/uiswing/layout/gridbag.html 5) GridLayout: Create an N-by-M grid. As you add() components, the GridLayout manager places them across the first row until full, then the 2nd, 3rd, etc... The add() method may be different for different layout managers. For example, BorderLayout needs the component's position in the container SETTING THE LAYOUT MANAGER + Simply call the panel's setLayout() function: JPanel pane = new JPanel(); pane.setLayout(new BorderLayout()); PROVIDING HINTS ABOUT A COMPONENT + Size - use the setPrefferedSize(), setMaximumSize(), and setMinimumSize() methods. - only BoxLayout pays attention to setMaximumSize() - setPrefferedSize() is very useful!! + Alignment - use the container's setAlignmentX() and setAlignmentY() methods http://java.sun.com/docs/books/tutorial/uiswing/layout/using.html ----------------------------------------------------------------------- 4) Handling Events + an event occurs each time a user pushes a button, moves the mouse, types a key, etc. - any object can be notified of the event. You just need the object to implement the appropriate interface on the right event source + Just a few types of listeners: - ActionListener: button presses, Return in text, choose menu item - WindowListener: user opens, closes, or resizes a frame - MouseListener: user presses mouse while over component - A bunch of others + Each event represented by an object that has info about the event. - This information includes the "event source", which allows you to write code based on which component created an event - For example, which button was pressed? + Example: how to implement an event handler 1) When declaring the class that serves as the listener, specify that the class implements the listener's interface - public class myClass implements ActionListener {... 2) Add the listner to any object you want - myButton.addActionListener(instaneOfMyClass); 3) Define the methods of the interface in the class - public void actionPerformed(ActionEvent e) { if(e.getSource() == myButton) { //your code here } } - Now when a user clicks on the button, it fires an ActionEvent. This event is picked up by the ActionListener (the instance of myClass), and the actionPerformed() method is invoked, where the argument is the ActionEvent object that gives info about the event and source. + You can also use an anonymous inner class to handle events: myButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { //Whatever the button does } }); THREADS AND EVENT HANDLING + What is a thread? - think of it as a line of commands to execute (like a program) - a program can have multiple threads that each perform some task - these are executed in parallel - simple programs have only 1 thread - will talk about these later + Event-handling code all executes in one thread, the event-dispatching thread. - ensures that events are processed in series (not in parallel) - necessary... think of pressing one button then another that depends on the first - painting also occurs in the event-dispathing thread - *** thus, the GUI is FROZEN when the actionPerformed() method is executing *** - *** make event handling code fast!!! (or use threads... later) *** http://java.sun.com/docs/books/tutorial/uiswing/overview/event.html ----------------------------------------------------------------------- 5) Dialog boxes DIALOGS + windows that are more limited than frames - use JOptionPane to create simple, standard dialogs - showConfirmDialog, showInputDialog, showMessageDialog, showOptionDialog (unifies all 3 above) - see API for explanation - use JDialog to create custom dialogs directly - some already created: JFileChooser, JColorChooser + every dialog depends on an exisiting frame - when frame is destroyed, so is dialog + dialog can be "modal" - blocks all input to other windows in program - all dialogs made from JOptionPane are modal. Use JDialog to make non-modal dialogs see http://java.sun.com/docs/books/tutorial/uiswing/components/dialog.html for info. Look for CustomDialog.java on that page for an example of how to make your own. http://java.sun.com/docs/books/tutorial/uiswing/components/dialog.html ----------------------------------------------------------------------- 6) Useful methods + frame.pack(); - causes the window to be sized to fit the preferred sizes of all components it contains. Basically it "packs" everything together + frame.show(); - makes the window visible Usually call pack() and show() at the end the constructor for whatever class defines a gui, which either extends JFrame (or even JPanel). + frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE); - tells the program to stop when the window is closed. Otherwise it will still be running in the background, just not displaying anything - can accomplish the same thing by implementing the WindowListener interface