Button Clicks and ActionListeners


When you click a Swing button, some action should take place. When you click on the Add button in CoursesPanel, you want a new course to show up in the list of courses. Code to accomplish this will require three steps:

1.

Read the contents of the course department and course number text fields.

2.

Create a new Course object using the course department and course number text.

3.

Put the Course object in the model for the courses list.

Adding a new course with these steps is a mixture of user interface responsibility and business logic. Remember, you want CoursesPanel to be a more or less dumb class that just shows information to the user. Clicking a button is a controller event, one that you can respond to with an action. The details of the actionthe business logicdoes not belong in CoursesPanel.

For now, you still need to write a test for the view class. Code in the panel class still needs to tell "someone" to take action when a user clicks the Add button. The panel test will prove that clicking on an Add button triggers some actionan action that has yet to be defined.

You can wire a button click to an action method by using a callback. Java supplies the interface java.awt.event.ActionListener for this purpose. To implement ActionListener, you code the action method actionPerformed. Code in actionPerformed should do whatever you want to happen when someone clicks the button.

After defining an ActionListener class, you can assign an instance of it to the button. When a user clicks the button, logic in JButton calls back to the actionPerformed method on the ActionListener object.

 package sis.ui; import junit.framework.*; import javax.swing.*; import java.awt.*; import java.awt.event.*; import static sis.ui.CoursesPanel.*; public class CoursesPanelTest extends TestCase {    private CoursesPanel panel;    private boolean wasClicked;    protected void setUp() {       panel = new CoursesPanel();    }    ...    public void testAddButtonClick() {       JButton button = panel.getButton(ADD_BUTTON_NAME);       wasClicked = false;       panel.addCourseAddListener(new ActionListener() {          public void actionPerformed(ActionEvent e) {             wasClicked = true;          }       });       button.doClick();       assertTrue(wasClicked);    } } 

You will usually want to implement listeners as anonymous inner classes. Here, the sole job of the ActionListener is to ensure that the actionPerformed method gets called when the button is clicked. The JButton class provides the method doClick to emulate a user clicking on a button.

CoursesPanel must supply a new method, addCourseAddListener. This method simply attaches the ActionListener callback object to the JButton object. Some production client using CoursesPanel will be responsible for defining this callback and passing it to the view. The view remains blissfully ignorant of any business logic.

 package sis.ui; import javax.swing.*; import java.awt.*; import java.awt.event.*; public class CoursesPanel extends JPanel {    ...    private JButton addButton;    ...    private void createLayout() {       ...       addButton = createButton(ADD_BUTTON_NAME, ADD_BUTTON_TEXT);       ...    }    void addCourseAddListener(ActionListener listener) {       addButton.addActionListener(listener);    }    ... } 

You must change addButton to be a field and not a local variable for this to work.

The method addCourseAddListener is a single line of code. For view code other than layout, this is your ideal. If you find yourself putting while loops, if statements, or other convoluted logic in your view class, stop! It likely contains business or application logic that you should represent elsewhere.



Agile Java. Crafting Code with Test-Driven Development
Agile Javaв„ў: Crafting Code with Test-Driven Development
ISBN: 0131482394
EAN: 2147483647
Year: 2003
Pages: 391
Authors: Jeff Langr

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net