CS51 - Spring 2010 - Lecture 11

  • Exercises 11.4.2, 11.4.3

  • show BadButtonPanelDrawingProgram demo
       - There is a JButton object that creates a usable button
       - Instead of using a dropdown menu and clicking in the canvas, change it so that when we click a button, the object is created
          - avoids accidentally creating a new object when we're trying to drag an object
       - How do you think the GUI setup was constructed here? Why does it look funny?
          - the FlowLayout doesn't wrap around

  • GridLayout
       - splits the panel into a row by col grid
       - each component takes up the same amount of space, i.e. the grid perfectly splits up the space
       - elements are added in reading order, that is from left to right and then top to bottom
          - specify rows then columns, for example 3, 2 is 3 rows and 2 columns
          - first item added goes in upper left, then upper right, then middle left, then middle right, etc

  • show ButtonPanelDrawingProgram demo
       - how do we create this?
          - one large JPanel with a one row and two columns
          - one JPanel (with the default FlowLayout) where we add the buttons
             - add that JPanel to the large JPanel, so it will end up in the first position
          - add the JComboBox to the large JPanel, so it will end up in the second, bottom position
          - finally, add the large JPanel to the SOUTH of our content pane (and of course, validate :)
       - how do you think we handle the button clicking?
          - remember the things we need to do to handle GUI events
             - implements ActionListener
             - add the actionPerformed method
             - add "this" object as a listener using addActionListener to the object(s) that we want to respond to
          - need to addActionListener for all three of the buttons!
             - what complication does this add?
                - in actionPerformed, need to figure out which of the buttons caused actionPerformed to be called

  • look at ButtonPanelDrawingProgram code
       - begin method looks like we predicted
          - create new JButtons
          - addActionListener(this) for all three
          - notice that we're also listening to our colorMenu
          - bottomPanel.setLayout(new GridLayout(2, 1));
       - actionPerformed
          - need to handle 4 different things (the three buttons, the one drop down menu)
          - evt.getSource() gives us the object that generated the event
             - why can we use '=='?
                - we literally want to know if it was exactly that button that generated the event

  • show ColorSlider demo
       - what do you think the big box at the top that changes color is?
          - it's just a FilledRect
       - how are we changing the color?
          - setColor
       - we can adjust the sliders and in response to that, our program updates the color
          - Another interface ChangeListener
             - one method: public void stateChanged(ChangeEvent evt)
             - similar to our other listeners, we have an: addChangeListener(this) method
          - this pattern should start to look familiar:
             - implements ChangeListener
             - add the stateChange method
             - tell the program that "this" will listen/respond to any changes made by the object (in this case, the sliders)
       - why do we have two different interfaces ActionListener and ChangeListener
          - action events happen much less frequently, i.e. based on a click
          - change events are much more frequent and continuous, i.e. based on a dragging of the mouse
          - we wouldn't want the overhead of all the action event code in the stateChanged method
       
       - JSlider
          - it's only the slider bar (not the text)
       - JLabel for adding text (similar to our "Text" object, but it's a GUI component)
       - let's look at the layout, how can we design this?
          - two different ways:
             - one large JPanel with a 3, 1 GridLayout (3 rows, 1 column)
             - for each slider we have a JPanel
                - 1, 3 GridLayout (1 row, 3 columns)
                - JLabel
                - JSlider
                - JLabel
             - one large JPanel with a 3, 3 GridLayout (3 rows, 3 colummns)
                - don't need individual JPanels for each set of slider components
                - just add them all to the large JPanel individually

  • look at ColorSlider code
       - what information do you think we need to construct a new JSlider (i.e. what's going to go in the constructor)?
          - need to know whether it's a vertical or horizonal slider
          - range, specified by a minimum value and a maximum value
          - initial, starting value
       - the stateChanged method is going to be called everytime any of the sliders changes values
       - what do we want to do when a slider changes value?
          - get the value from each of the sliders
             - getValue() method returns the value
          - set the color of our FilledRect to be the new color indicated by the sliders
          - update the text for all of the sliders
             - setText(...) (similar to setText for Text)
             - why do we do "" + redValue? what does this accomplish?
       - we could try and figure out which of the sliders changed using evt.getSource(), but it would just make the code more complicated

  • show ColorMixer demo
       - rather than using a JSlider, we can use a JTextField to allow the user to enter data
          - getText() method allows us to get the text entered in the JTextField
          - how do we know when to check the data?
             - when the user hits "return" it triggers an event
             - what type of listener do you think we would use?
                - ActionListener (discrete, user generate event)
                - we can addActionListener to respond to user inputs
       - what does the layout look like?
          - 3, 2 GridLayout
          - each row has a JLabel and a JTextField
       - when we're allowing a user to enter data, what do we need to be careful of?
          - need to make sure the the user enters valid data
             - in this case, it has to be a number and that number has to be between 0 and 255

  • look at ColorMixer code
       - when we're creating a GridLayout layout manager, there are two additional parameters we can specify (if we want) that modify the amount of space in between the rows and columns
          - new GridLayout(3, 2, 10, 5)
             - 3 rows
             - 2 columns
             - 10 pixel horizontal gap (i.e. between each column)
             - 5 pixel vertical gap (i.e. between each row)
       - addActionListener(this) for all of the JTextFields
       - actionPerformed method
          - get the text values
          - create a new color and set the color of the FilledRect
          - what does the getColorMix method do?
             - it's a private helper method
             - why is it private?
                - only used internally to the class
             - gets the value from the JTextField and checks to see if it's the appropriate range
             - what if it's not in the range?
                - if it's less than the minimum value, it's set to the minimum value
                - if it's larger than the maximum value, it's set to the maximum value
          - why use a helper method?
             - whenever you find yourself doing repeated work, make a method!

  • what if we want multiple lines of text, like a pararaph, etc?
       - JTextArea
       - same basic premise as JTextField, but multiple lines
       - look at the TextApplet example in the book

  • show Interesting demo