6.7 The ExitDialog class

The exitDialog used by the MenuBarTuttle class, attached to the File menu Exit … item, is an instance of the ExitDialog class whose appearance and behaviour is shown in Figure 6.7.

Figure 6.7 The ExitDialog appearance and behavior.

The dialog is posted in a modal manner, in response to the user pressing the Exit … item on the File menu. It is appropriate for this dialog to be presented to the user in a modal manner as the possibility of an application terminating is sufficiently important for the user to be forced to attend to it. Once posted pressing either of the buttons will un-post the dialog causing a transition to the STD's terminal state. If the yes button is pressed this transition will generate an action event, allowing the MenuBarTuttle class to be informed that the user indicated that the application should be shut down.

The dialog is constructed with a MessageCanvas instance, as described in Chapter 3, containing a two line message mounted in its "Center" location and a Panel containing the two Buttons in its "South" location. The ExitDialog instance attribute declarations and constructor are as follows.

0018  class ExitDialog extends    Dialog  0019                   implements ActionListener {  0020   0021  private Window          itsParentWindow; 0022  private ActionListener  itsListener; 0023   0024  private Panel            buttonPanel; 0025  private MessageCanvas    message;                       0026  private Button           yesButton; 0027  private Button           noButton;  0028   0029     protected ExitDialog( Frame          itsParentFrame, 0030                           ActionListener listener) {  0031                                        0032        super( itsParentFrame, "Exit", true); 0033        this.setFont( itsParentFrame.getFont()); 0034        this.setBackground( itsParentFrame.getBackground()); 0035        itsParentWindow = (Window) itsParentFrame; 0036        itsListener = listener; 0037   0038        message = new MessageCanvas( "Are you sure\nyou want to exit?"); 0039        message.setBackground( Color.white); 0040   0041        buttonPanel = new Panel(); 0042        buttonPanel.setBackground( Color.white); 0043         0044        yesButton = new Button( "yes");       0045        yesButton.setActionCommand("yes");  0046        yesButton.addActionListener( this);  0047        buttonPanel.add( yesButton); 0048   0049        noButton = new Button( "no");  0050        noButton.setActionCommand("no");  0051        noButton.addActionListener( this);             0052        buttonPanel.add( noButton); 0053   0054        this.add( message,     "Center"); 0055        this.add( buttonPanel, "South"); 0056        this.pack(); 0057     } // End ExitDialog constructor.

The constructor commences, on line 0032, by calling its parent (super) constructor, specifying as the first argument the Frame instance which this dialog window is to be associated with. This argument is received as the first argument of the ExitDialog constructor. The remaining two arguments of the Frame constructor call are the title to be used for the dialog window and the modal state (true) of the dialog. The constructor continues, on lines 0033 and 0034, by configuring the appearance of the dialog and, on lines 0035 and 0036, storing the identities of the arguments to the constructor in instance attributes.

Lines 0038 to 0056 then construct, configure and assemble the components of the dialog: a MessageCanvas instance in its "Center" location and a Panel containing two buttons in the "South" location, producing the appearance shown in Figure 6.7. The ActionListener of both buttons is specified as the ExitDialog instance itself, which accordingly declares itself to implement the ActionListener interface. The constructor creates the dialog ready for use but it does not become visible to the user until its setVisible() method, implemented as follows, is called with a true argument.

0063     protected void setVisible( boolean showIt) {  0064      0065     Point      itsParentsLocation; 0066     Dimension  itsParentsSize; 0067     Point      itsLocation; 0068     Dimension  itsSize; 0069   0070        if ( showit) {  0071           itsParentsLocation = itsParentWindow.getLocationOnScreen(); 0072           itsParentsSize     = itsParentWindow.getSize(); 0073           itsSize            = this.getSize(); 0074           itsLocation        = new Point(); 0075         0076           itsLocation.x = itsParentsLocation.x +  0077                           itsParentsSize.width/2 -  0078                           itsSize.width/2; 0079           itsLocation.y = itsParentsLocation.y +  0080                           itsParentsSize.height/2 -  0081                           itsSize.height/2;                           0082           this.setLocation( itsLocation);              0083        } // End if. 0084        super.setVisible( showIt);             0085     } // End show.

The boolean showIt argument indicates if the dialog should be made visible to the user or hidden from them. This method only need be concerned with intervening when the dialog is to be shown and the if structure between lines 0070 to 0083 effects this. The contents of this decision are identical with a part of the implementation of the PostItNote setVisible() method in Chapter 3, and ensures that the dialog is always presented to the user centered within its parent, MenuBarTuttle, window. Following the if structure, on line 0084, the parent, Dialog, setVisible() method is indirected to passing onward the showIt argument to actually make the dialog visible, or hide it if showIt is false.

The only other method of the ExitDialog class is the actionPerformed() method, as follows.

0085     public void actionPerformed( ActionEvent event) { 0086        this.setVisible( false); 0087        if ( event.getActionCommand().equals( "yes")) {  0088           itsListener.actionPerformed( new ActionEvent( this,  0089                                        ActionEvent.ACTION_PERFORMED, 0090                                        "exit please"));         0091        } // End if.    0092     } // End actionPerformed.        0093  } // End ExitDialog.

This method can only be called in response to a press of either of the buttons on the ExitDialog and commences by calling the ExitDialog's setVisible() method, with the argument false, to un-post it from the desktop. If this method was called as a consequence of the "yes" button being pressed the user has confirmed that the applet should terminate. This results, on lines 0088 to 0090, in the actionPerformed() method of the ActionListener passed to the constructor being called with an ActionEvent argument containing the commandString "exit please".

The MenuBarTuttle constructs its exitDialog instance at the end of its init() method as follows.

0065        exitDialog = new ExitDialog( tuttleFrame, this);  

Hence the identity of the ActionListener to which the ActionEvent is dispatched when the "yes" button is pressed is the MenuBarTuttle instance, whose processing of "exit" commands within its performAction() method, given in detail above, is as follows.

0083        if ( theCommand.equals( "exit")) {  0084           if ( theArgument.equals( "show")) {           0085              exitDialog.setVisible( true);  0086           } else if ( theArgument.equals( "please")) {  0087              System.exit( 0); 0088           } // End if.      

The Exit … button on the File menu of the interface will send the commandString "exit show" to this method and this will result, in line 0085, in the exitDialog setVisible() method being called, with the argument true, making the dialog visible to the user in the middle of the applet's window. If the user confirms that the applet should terminate this method will be called again with the commandString "exit please", resulting in the System.exit() call, on line 0087, terminating the applet. The argument 0 to the exit() method call indicating that the application concluded normally.

A common novice's design error would be to call the System.exit() method within the ExitDialog's implementation. With this approach the applet is not made aware that the user has confirmed that the applet should conclude before it terminates and so has no opportunity to tidy up, for example closing any open streams, before the applet finishes.

Design Advice

Only the applet, or application, class should be responsible for finishing and should conclude gracefully closing any streams and releasing any other resources as required.

As the applet stands at the moment the application can also be immediately terminated by using the appletviewer's window frame exit control. In the Windows '95 illustrations used in this book this is the X button at the top right. To prevent this from happening, or cause it to happen in some environments, the WindowEvents dispatched to the Frame will have to be intercepted and handled. To accomplish this, the declaration of the MenuBarTuttle class will have to be amended to indicate that it implements the WindowListener interface, as follows.

0022  public class MenuBarTuttle extends    Applet  0023                             implements ActionListener,  0024                                        WindowListener {

The tuttleFrame will have to be informed of the identity of its WindowListener object by calling its addWindowListener() method, as follows.

0047      tuttleFrame.addWindowListener( this);

Having done this the MenuBarTuttle class will have to supply the seven methods required by the WindowListener interface of which only one, the windowClosing(), method need actually do anything. The implementation of these method is as follows.

0168   public void windowClosing( WindowEvent event) {   0169      exitDialog.setVisible( true);      0170   } // End windowClosing . 0171    0172   public void windowOpened( WindowEvent event)      {} // End windowOpened.     0173   public void windowClosed( WindowEvent event)      {} // End windowClosed. 0174   public void windowIconified( WindowEvent event)   {} // End windowIconified. 0175   public void windowDeiconified(WindowEvent event)  {} // End windowDeiconified.   0176   public void windowActivated( WindowEvent event)   {} // End windowActivated. 0177   public void windowDeactivated( WindowEvent event) {} // End windowDeactivated.   

The windowClosing() method calls the exitDialog setVisible() method to post the dialog onto the desktop and as it does not dispatch to its super windowClosing() method prevents the window from actually closing. The remaining six methods are dummy methods which do nothing, but have to be supplied in order to satisfy the WindowListener interface, and have been laid out in a manner which emphasizes this to anyone reading the code. The consequence of these changes is that when the exit control on the Frame is pressed the exitDialog will be posted and only if the user confirms the exit by pressing the "yes" button will the applet actually terminate.

In this implementation the only instance attributes which strictly require visibility outside the scope of the constructor are itsParentWindow, required by the setVisible() method, and itsListener, required by the actionPerformed() method. However Java has a rule that when a constructor calls its parent (super) constructor, this call has to be the very first statement in the constructor. This rule prevents the remaining instance declarations, on lines 0024 to 0027, from being declared as local variables of the constructor. A more elegant solution would be to include an additional private constructDialog() method within the class, declaring the components as local variables, and calling the method from the constructor; but in a class a simple as this declaring them as private instance attributes seems acceptable.



6.8 The VersionDialog class

6.6 The Dialog class

A Java GUI programmer's primer
Java GUI Programmers Primer, A
ISBN: 0139088490
EAN: 2147483647
Year: 1998
Pages: 85
Authors: Fintan Culwin

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