CS51 - Spring 2010 - Lecture 10

  • Exercise 10.5.2
    public interface Alphabet{
       public void x( Color aColor );
       public double y( int number );
       public boolean z( Location point );
    }

    Class A implements Alphabet:
    methods: public void x( Color aColor );
       public double y( int number );
       public boolean z( Location point );
       public String w();

    Class B implements Alphabet:
    methods: public void x( Color aColor );
       public double y( int number );
       public boolean z( Location point );
       public String w();
       public void v (boolean b);

    a. private Alphabet letter = new A();
    b. private A letter = new A();
    c. private A letter = new Alphabet();
    d. private Alphabet letter = new B();
    e. B letter = new B();
    letter.v(true);
    f. Alphabet letter = new B();
    letter.v(true);
    g. Alphabet letter = new A();
    letter.w();
    h. A letter = new A();
    letter.w();
    i. Alphabet letter = new A();
    letter.x( Color.RED );

  • responding to keyboard input
       - KeyListener interface
          - public void keyPressed(KeyEvent e);
          - public void keyTyped(KeyEvent e);
          - public void keyReleasted(KeyEvent e);
       - Similar to our onMousePress, etc methods but for the keyboard
       - When are these methods called?
          - a press is any time a key goes down
          - a release is any time a key come up
          - a type is a higher level operation and only happens when an actual character is type
       - show KeyDemo code
          - import java.awt.event.*;
          - "implements KeyListener"
          - must define all of the methods required by the interface!
             - you may not use all of them, but you still need to define them
             - leave them empty (i.e. no code in the body of the method) if you're not going to use them
          - System.out.println(...) prints information to the console
          - the KeyEvent variable passed in has information about the key that was pressed
             - each key on the keyboard has it's own unique int code, obtained from the getKeyCode() method
                - if you ever want to get this code, you can just run this program and see what that number is
             - you can also get the character press from the getKeyChar() method, though for somethings, like "shift" or the arrow keys, you'll get a '?'
          - in the begin method, you need to do a few things to tell the world that you this class wants to be told about keyboard events
             canvas.addKeyListener(this);
             this.addKeyListener(this);
             setFocusable(true);
       - show KeyDemo demo
          - notice that all three methods are called when I push down on a key (for most characters)
          - if I press "shift" and release I don't get a key typed, but I get a pressed and released
          - if I hold a key down, I get repeated calls
          - most of the time, we'll just want to use keyPressed

  • GUIs
       - Graphical User Interface
       - things like buttons, drop down menus, pull down menus, text fields, scroll bars
       - Three basic groups of things for doing GUIs in Java:
          - GUI components: these are the actual things (like buttons, text fields, sliders, etc.) that we want to put in our program
          - Containers: containers actually house the GUI components. Unlike the other objects we've seen so far, GUI components are NOT displayed when they're created, but need to be added to a container.
          - Layout managers: Unlike adding things to DrawingCanvas, we don't add GUI objects with positional information. Instead, all containers have a layout manager associated with them that describe how the GUI components that are added to the container will be positioned.
             - Why do you think we do this instead of using exact positioning?

  • WindowController
       - WindowController is a Container and so if you extend WindowController, then you can add GUI components to it
       - The layout manager for WindowController is called BorderLayout
          - you can add components to the North, South, East, West and Center
          - when you add a component, it fills up the entire space
       - For WindowController, the canvas object sits in the Center, so in general, don't add anything there
          - extend Controller if you don't need the canvas and want to add components to the center

  • show ComboBoxDrawingProgram demo
       - We only have one GUI component: JComboBox
       - What will this class look like?
          - begin
             - construct the JComboBox
                - add the selection items to the box
             - add it to the South
             - setup the filled rects
             - setup a framed rect
          - onMouseClick
             - if we clicked inside the "drawing" area
                - create the appropriate object
                   - need to figure out what the settings are from the JComboBox
             - if we clicked in any of the colors
                - set the color of the last created object
          - onMousePress, onMouseRelease, onMouseDrag
             - handle the dragging of the current object
             - why do you think we can only drag the last created object?

  • show ComboBoxDrawingProgram code
       - imports
          - import java.awt.*;
          - import java.swing.*;
       - variables
          - For all of the demo programs, you should ask yourself, why do we need that variable as an instance variable?
          - private JComboBox drawingArea
             - why do we need an instance variable?
                - we're going to need to get attributes from the box when the user clicks
          - private DrawableInterface newShape
             - why is it DrawableInterface?
                - so we can add either FramedRect, FilledRect or FilledOval
       - begin
          - To add a GUI object, there are a few steps
             1. create the gui component and do any initialization (in this case, adding the menu items)
             2. Add it to the content pane Container for the WindowController
                - Container contentPane = getContentPane(); // gets the Container associated with our WindowController
                - contentPane.add(...)
             3. validate the content pane (things may not behave appropriately without doing this)
                - contentPane.validate()
          - BorderLayout.SOUTH adds to the south (similarly, BorderLayout.NORTH, ..., can be used)
       - onMouseClick
          - We get the choice of which item is selected:
             - Object choice = figureMenu.getSelectedItem();
             - it's just a generic "Object" (we'll talk a bit more about the Object class later)
          - check to see which of the choices it is using .equals
          - for the colors, we're just using FramedRects and checking if our mouse click is in there

  • show DoubleComboBoxDrawingProgram demo
       - What's changed?
          - We've added another JComboBox for color selection
          - Notice that the the color of the last created object changes with respect to changes in the menu
             - how do you think this happens?
                - similar to the KeyListener interface, there is an ActionListener interface

  • show DoubleComboBoxDrawingProgram demo
       - notice that the program responds to changes in the color menu
       - what do we need to change?
          - another JComboBox for the color controlling
          - add it to BorderLayout.NORTH
          - somehow respond to color menu changes

  • look at DoubleComboBoxDrawingProgram code
       - begin()
          - construct the JComboBox for the color menu
          - colorMenu.addActionListener(this) //DON'T FORGET THIS
          - add the color menu to BorderLayout.NORT
       - Responding to changes in GUI components
          1. implements ActionListener
             - make sure to import java.awt.event.*;
          2. only one method to implement for the interface
             public void actionPerformed(ActionEvent event)
          3. Once you've done that, your class is now ready to respond to Action events, but you need to tell it which events it should listen to. To do this, after you've created your JComboBox (say it's named colorMenu) you need to tell our current object to listen for events generated from the JComboBox
             colorMenu.addActionListener(this);

          - now, everytime a change is made to the color menu, our actionPerformedMethod will be called
       - implements ActionListener
       - actionPerformed
          - Why the check for null? What is null?
             - An object variable (i.e. everything but our built-in types) that is unassigned is by default given the null value, meaning it doesn't reference anything
             - if we haven't created any objects yet, newShape will be null
          - similar to before, we get the Object associated with the menu:
             Object colorChoiceString = colorMenu.getSelectedItem();
          - then use .equals to see which option was selected

  • show PanelComboBoxDrawingProgram demo
       - We said that when we can only add one thing to a BorderLayout area. If we need to add two things to an area, how do you think we do it?
       - JPanels!

  • JPanel
       - A JPanel is another Container that can hold GUI objects
          - by default, a new JPanel uses a FlowLayout
             - in a FlowLayout, objects are just put next to eachother starting from the left to right
          - the "add" method is used to add GUI components to the JPanel
          - then add the JPanel to whatever part of the main content pane that you want

  • look at PanelComboBoxDrawingProgram code
       - begin
          - create our JComboBoxes as before
          - create a new JPanel
          - add the figure and color menus to the JPanel
          - add the JPanel to the content pane at BorderLayout.SOUTH
       - everything else stays the same. We just moved the around where the different GUI components were within the window

  • debugging
       - simplest way, System.out.println()
       - debug functional components!!!
          - if you program one method, test out that one method by itself and make sure it works
             - you can even test parts of a method by commenting things out to make sure a sub-part is working
          - when you've tested all of the methods individually in a class, then test the entire class
          - save you a lot of time debugging
          - don't just code everything up and then try and debug the whole thing!
       - learn to use the debugger
          - set a breakpoint
             - a breakpoint is a place in the code (if you're running in debugging mode) where the program execution will stop if it reaches that line
          - once you've hit a break point
             - you can analyze all the variables at that point
             - you can look at the call stack, i.e. how you got to where you're at
             - continue through the code
                - continue (i.e. start running again)
                - step-over (step to the next line)
                - step-into (step in to the method being called at that line, if applicable)
                - step-return (finish the execution of this method, but stop immediately where it was called from)