29
Session 9 CannonWorld, Event-driven Programming, and Border Layout

Session 9 CannonWorld, Event-driven Programming, and Border Layout

Embed Size (px)

Citation preview

Page 1: Session 9 CannonWorld, Event-driven Programming, and Border Layout

Session 9

CannonWorld, Event-driven Programming, and Border Layout

Page 2: Session 9 CannonWorld, Event-driven Programming, and Border Layout

The CannonWorld

Budd has added two new objects to our cannon game:• a button at the top of the window. When the user presses

the button, the cannon fires a cannonball.• a slider at the right. When the user adjusts the position of

the slider, the cannon changes the angle at which it fires.

Page 3: Session 9 CannonWorld, Event-driven Programming, and Border Layout

An Example: The CannonWorld

The user can cause these events at any time. The user controls the flow of the program, not the game world.

Control of the game changes from

“Do this , then that, then this other thing.”

to

“Respond to the user’s action.”

Page 4: Session 9 CannonWorld, Event-driven Programming, and Border Layout

Event-Driven Programming

Object-oriented programming shifts program control from a top-level “main” program into a set of collaborating objects.

This new emphasis also makes it easier for us to write programs that shift control from the program to the user.

Page 5: Session 9 CannonWorld, Event-driven Programming, and Border Layout

Event-Driven Programming

This style of programming is called event-driven because it builds program control around one or more events that the user causes. The program retains low-level control of how to respond to each kind of event that the user can initiate.

Event-driven programming can also be done in environments with little or no user interaction. In such environments, the events are generated by other programs: objects that generate events to request services.

Page 6: Session 9 CannonWorld, Event-driven Programming, and Border Layout

Event-Driven ProgrammingIn Java, the programmer defines objects called listeners that wait for

and respond to user-initiated events.

A listener can be attached to any object capable of generating an event caused by the user:

• the mouse– moving the mouse– pressing and releasing mouse buttons

• the keyboard– pressing any key

• active components such as buttons and sliders

We can also attach listeners to non-UI components, but we won’t write that sort of program until much later in the semester.

Page 7: Session 9 CannonWorld, Event-driven Programming, and Border Layout

Listeners in the CannonWorldEach GUI component needs a listener to wait for

the user to manipulate and then relay the event to the CannonWorld.

private Scrollbar slider;private class ScrollBarListener implements AdjustmentListener {

public void adjustmentValueChanged( AdjustmentEvent e ){angle = slider.getValue();message = "Angle: " + angle;repaint();

}}

Page 8: Session 9 CannonWorld, Event-driven Programming, and Border Layout

Listeners in the CannonWorldprivate class FireButtonListener implements ActionListener {

public void actionPerformed( ActionEvent e ) {double radianAngle = angle * Math.PI / 180.0;double sinAngle = Math.sin(radianAngle);double cosAngle = Math.cos(radianAngle);cannonBall = new CannonBall( 20 + (int) (30 * cosAngle),

dy(5+(int) (30 * sinAngle)),5,12 * cosAngle,-12 * sinAngle );

repaint();}

}

Page 9: Session 9 CannonWorld, Event-driven Programming, and Border Layout

Listeners in the CannonWorld

public CannonWorld() {setSize ( FrameWidth, FrameHeight );setTitle( "Cannon Game" );Button fire = new Button( "fire" );fire.addActionListener( new FireButtonListener() );add( "North", fire );slider = new Scrollbar( Scrollbar.VERTICAL, angle, 5, 0, 90 );slider.addAdjustmentListener( new ScrollBarListener() );add( "East", slider );

}

Page 10: Session 9 CannonWorld, Event-driven Programming, and Border Layout

Listeners as Inner ClassesWhat is an inner class?

Any class defined within another class definition:

public class CannonWorld extends Frame {...private class FireButtonListener ... {

...}...

}

How do we create one?“Just do it.”

Why do you suppose FireButtonListener is private?

Page 11: Session 9 CannonWorld, Event-driven Programming, and Border Layout

Listeners as Inner Classes

Why do we create them?• For convenient access to the private

members of the outer class.• For simple collaboration between pure

masters and slaves.• Almost only for listeners.

Notice that one .java file can produce many .class files.

Page 12: Session 9 CannonWorld, Event-driven Programming, and Border Layout

Listeners Implement Interfaces

Examples• ScrollBarListener implements AdjustmentListener• FireButtonListener implements ActionListener

Review: What is an interface?• A list of responsibilities.• A set of messages to which an object promises to

respond.• Sometimes called a protocol.• Like a class with no behavior.

Page 13: Session 9 CannonWorld, Event-driven Programming, and Border Layout

Why Use Interfaces

Why do we use interfaces in this program?• When the user presses a button, the Java run-

time system sends an actionPerformed() message to any object that is listening for the button’s events. If we want our listener to listen, it must listen for that particular message.

• When the user adjusts a slider, the Java run-time system sends an adjustmentValueChanged() message to any object that is listening for the slider’s events. If we want our listener to listen, it must listen for that particular message.

Page 14: Session 9 CannonWorld, Event-driven Programming, and Border Layout

Why Use Interfaces

More generally, why do we use interfaces?

• To allow our objects to work inside an existing framework.

• To allow programmers to create objects that fulfill responsibilities — without committing to how their objects do so!

Page 15: Session 9 CannonWorld, Event-driven Programming, and Border Layout

Layout Managers• Frame is a subclass of the Container class

– so it can hold objects such as buttons, scroll bars, etc.

– layout manager assigns locations to these objects within the container

– the default LayoutManager is BorderLayout

North

South

CenterWest East

Page 16: Session 9 CannonWorld, Event-driven Programming, and Border Layout

Layout Managers• Five standard types of layout managers:

– BorderLayout– GridLayout - creates an rectangular array of

components– FlowLayout - places components in rows left to

right, top to bottom– CardLayout - stacks components vertically with

only one visible at any one time– GridBagLayout - most general, but most

complex. It allows for a nonuniform grid of squares with components placed in various positions within each square.

Page 17: Session 9 CannonWorld, Event-driven Programming, and Border Layout

An Exercise

Add to our CannonWorld a button that allows the user to change the color of the cannonball from blue to red to yellow to blue....

Place the button on the lefthand side of the window.

Page 18: Session 9 CannonWorld, Event-driven Programming, and Border Layout

Steps to the solution:

1. Add a button to the CannonWorld.2. Add a listener class to CannonWorld.

The listener’s actionPerformed method needs to tell the ball to take the next color. It could have an if-statement that toggles the colors in sequence, but...

• Shouldn’t the ball be controlling its own color, rather than the application using the ball?

So in my solution, I decided to have the CannonBall respond to a nextColor() message and toggle its own color.

Page 19: Session 9 CannonWorld, Event-driven Programming, and Border Layout

More Steps to the Solution

The next question is, do I add a nextColor() method directly to the CannonBall class, or do I create a subclass?

In general, if we need a new kind of object, then we should create a new kinds of object.

(If a particular method turns out to be more generally useful than we anticipate, then we can always refactor the solution so that the method lives higher in the class hierarchy.)

So:3. Implement a ChangingCannonBall class.4. Use instances of ChangingCannonBall in the CannonWorld.

Page 20: Session 9 CannonWorld, Event-driven Programming, and Border Layout

Using GridLayout• MemoPad uses GridLayout exclusively, but

it nests GridLayouts:– MemoPad frame is GridLayout( 3, 1 )

• top row contains a Panel with GridLayout( 2, 2 )• middle row contains a Panel with GridLayout( 1, 3 )

Page 21: Session 9 CannonWorld, Event-driven Programming, and Border Layout

Using GridLayout– MemoPad frame is GridLayout( 3, 1 )

Page 22: Session 9 CannonWorld, Event-driven Programming, and Border Layout

Using GridLayoutpublic class MemoPad extends CloseableFrame{ ... public MemoPad() { database = new DefaultMemoDatabase();

setLayout( new GridLayout( 3, 1 ) ); setSize( 300, 140 ); setTitle( "Memo Pad " );

fieldPanel = new FieldPanel(); fieldPanel.setSize( 300, 80 ); add( fieldPanel );

buttonPanel = new ButtonPanel( this ); buttonPanel.setSize( 300, 30 ); add( buttonPanel );

messagePanel = new MessagePanel( ".. No messages .." ); messagePanel.setSize( 300, 30 ); add( messagePanel ); }

Page 23: Session 9 CannonWorld, Event-driven Programming, and Border Layout

Using GridLayoutpublic class FieldPanel extends Panel{ private TextField keyField; private TextField valueField;

public FieldPanel() { setLayout( new GridLayout( 2, 2 ) );

keyField = new TextField( 20 ); valueField = new TextField( 20 );

add( new Label( "Key:" ) ); add( keyField ); add( new Label( "Value:" ) ); add( valueField ); }...

Page 24: Session 9 CannonWorld, Event-driven Programming, and Border Layout

Using GridLayoutpublic class ButtonPanel extends Panel { private MemoPad memos;

public ButtonPanel( MemoPad p ) { memos = p;

setLayout( new GridLayout( 1, 3 ) );

Button insertButton = new Button( "Insert" ); insertButton.addActionListener( new InsertButtonListener() ); add( insertButton );

Button findButton = new Button( "Find" ); findButton.addActionListener( new FindButtonListener() ); add( findButton );

Button removeButton = new Button( "Remove" ); removeButton.addActionListener( new RemoveButtonListener() ); add( removeButton ); }...

Page 25: Session 9 CannonWorld, Event-driven Programming, and Border Layout

Using Panels with BorderLayout• BorderLayout seems very restrictive, but

you can use a panel to hold several components in each “direction”.

Page 26: Session 9 CannonWorld, Event-driven Programming, and Border Layout

An ExercisePlace the “change color” button in a Panel

with the “fire” button along the top of the window.

Page 27: Session 9 CannonWorld, Event-driven Programming, and Border Layout

Test 1

• Tuesday, Feb. 14 (next week)

• Chapters: 1, 2, 3, 4, 5, 11, 14 (some file stuff)

• Test format: closed book, except one 8.5”x11” sheet of paper (both sides)

Page 28: Session 9 CannonWorld, Event-driven Programming, and Border Layout

Study Hints1. Go through each chapter and making a

list of the vocabulary terms that we have discussed. Could you explain what each means and how they relate to each other?

2. Review the slides I used during class and consider the points I have emphasized either directly on the slides or in addition to the slides.

Page 29: Session 9 CannonWorld, Event-driven Programming, and Border Layout

Study Hints3. Review the programs we have worked with (MemoPad,

Accumulator, LunarLander, Ball and BallWorld, CannonWorld, etc). I will provide you with any code I expect you to use/modify, but you don’t want to waste test time reviewing how the code actually works.

4. Read through the questions at the end of the chapters. Play the "second guess” the instructor game. That is, think about what you reviewed in the previous steps and think about how well each question would fit into these topics. Some of my questions will come from these questions. Others will be modifications to these questions based more on what I have chosen to emphasize.