You are hereAria User Guide / Section III: In Depth / Dialogs
Dialogs
Dialogs are frequently used to display special information, information that is not presented during the normal course of an application. Dialogs may be displayed in a modal way where they block input to the background windows while displayed, or in a non-blocking modeless fashion. Aria allows you build dialogs from pages just as you would build any other pages.
Creating a dialog
A new dialog can be created from the
File
menu by choosing
File | New | Aria | Aria Dialog
. Alternatively you can right click on the
pages
folder in the file view and choose
New Aria Page...
from the popup menu.
When the dialog is displayed enter the name of the new dialog and choose
Dialog
from the
Base class
list.
Structure
In Aria a dialog is special case of a page, the
Dialog
class is derived from
Page
and inherits all its facilities just as any other page would. However, whereas a typical page is displayed in the body of the application or within a frameset a dialog is displayed in a popup window.
The
Dialog
class is not itself the dialog object from the point of view of the underlying Java system, instead the
Dialog
is a container nested inside a dialog class or window.
The
Dialog
class can be subclassed and in this way you can customize the look and feel of the dialog plus modify the dialog's behavior, perhaps setting icons and changing headers. Normally such customization is not undertaken in applications but in some highly branded application you may not want the default operating system color scheme clashing with you applications look.
Display
Just as a page is shown with the
showPage
method a dialog can be called with the
showDialog
method:
Showing a dialog
pageMgr.showDialog( "myPopupDialog", translate( "MYDIALOG_TITLE" ), -1, -1 );
Where the last two parameters are the optional
X
and
Y
coordinates of the dialog, these coordinates can be set to that of the mouse or using the centre of the screen (pass a
-2
as the X coordinate ). A dialog may be displayed by calling the
showDialog
method instead of the
showPage
method.
Displaying a dialog
try { Dialog popupDialog = ( Dialog )pageMgr.loadPage( "myPopupDialog" ); Point pt = (( MouseEvent )getCurrentEvent() ).getPoint(); Point topLeft = myObject.getLocationOnScreen(); pt.translate( topLeft.x, topLeft.y ); popupDialog.setLocation( pt ); popupDialog.setModal( true ); popupDialog.pack(); popupDialog.showDialog( this ); } catch ( Exception e ) { e.printStackTrace(); }
A dialog will normally be displayed in the centre of the screen, but the location can be changed with a call to
setLocation
. The above example displays the dialog just below and to the right of the component `
myObject
' when the mouse is clicked on the component. (The
translate
method is used to adjust the current location since the current mouse position is relative to the component).
Once a modal dialog has been displayed the calling method is blocked till the dialog is dismissed. A dialog can be dismissed or closed by calling the
closeDlg
or
cancelDlg
methods.
For a modeless dialog it is sometimes useful to know when the dialog is dismissed even if the calling code is not blocked. The
showDialog
method therefore comes in a version that takes a reference to a callback method. The callback method is simply specified as the name of a response/handler method in the calling class. When the dialog is dismissed the callback method is invoked.
Packing
The decorations on a dialog (the border and header) can vary from platform to platform and it is therefore awkward to calculate the exact size of the dialog prior to display. Aria provides the
pack
method to resize the dialog so that all the components are visible. In addition the dialog page may specify a padding attribute to provide some extra space about the edges of the dialog and so that the components are not butted up against the edge of the dialog.
Padding a dialog
<Page resource="text_cm" class="org.formaria.awt.Dialog" padding="5">
The above example shows the declaration of a dialog in XML as mentioned above in Structure.. It is important to note that a dialog must be of class
Dialog
or a class derived from the
Dialog
class (in either the
org.formaria.swing.Dialog
or
org.formaria.awt.Dialog
variant). The
Dialog
class is a special form of page designed for use in Dialogs. Once the super class is defined, the content of the dialog can be setup like any other page.
Modality
A dialog can be display in a modal way where all input to background windows is blocked till the dialog is dismissed. To make a dialog modal simply call the
setModal
method for the dialog class.
Making a dialog modal
popupDialog.setModal( true );
Conversely a non- modal or modeless dialog can be created by setting this flag to
false
. A modeless dialog will allow user input to background window while the dialog is visible. Sometime modeless dialogs are used for parallel or alternate input mechanisms or for displaying summary or optional information in a separate window.
Other issues
Dialogs introduce a few additional issues due to the way they can interact with the rest of the system. The following sections cover some of these issues.
Setting the dialog location
The dialog is normally displayed at a position which centers it in relation to the the application. If you wish to explicitly set the location you can use a different version of the
showDialog
method:
Specifying the dialog location explicitly
Dialog popupDialog = ( Dialog )pageMgr.loadPage( "MyPopup" ); popupDialog.setModal( true ); popupDialog.pack(); popupDialog.showDialog( this, "My Dialog", new Point( 100, 100 ) );
Centering the dialog on screen
In another variation of dialog positioning you can use a helper method to position a modeless dialog on the center of the screen. A helper class is provided to do this:
Centering a modeless dialog
Dialog popupDialog = ( Dialog )pageMgr.loadPage( "MyPopup" ); popupDialog.setModal( false ); popupDialog.pack(); popupDialog.showDialog( this, "My Dialog", null ); AriaUtilities.centerOnScreen( popupDialog );
Resizable dialogs
The dialog has a resizable property which an be set via the
setResizable
prior to display of the dialog. However, this option only works if native headers (decorations) are used for the dialog. The headers can be set with the
setUseNativeHeaders
method. Also note that if you are using a resizable dialog that you should use layout managers in the dialog or else resizing will not resize the dialog's content.
Titles
The dialog title can be set with the call to
showDialog
as above or via a call to
setCaption
. Within the XML the title can be specified as an attribute of the
Page
element.
Setting the dialog title
XSwingHelper.showDialog( this, "MyPopup", "My Title", true, new Point( 100, 100 ));
Helpers
The dialog can also be displayed with the helper
SwingHelper
, or the AWT version
AwtHelper
.
Using SwingHelper to show a modal dialog.
<Page class="org.formaria.test.Customer" title="Customer Details">
Focus
Displaying a dialog will cause the focus to shift to the new dialog window once it is displayed. Therefore it is important to exercise caution when using focus event and handlers that trigger dialogs. In some cases this can prove problematic and a special method is available for suppressing the focus events temporarily, however it should be used with caution and should be well tested as it can be difficult to get the timing of such changes right.
Turning off focus event handling
getEventHandler().suppressFocusEvents( true );
Page activation
A dialog acts as any other page and will received the normal
pageCreated
,
pageActivated
and
pageDeactivated
messages. However the page from which the dialog display was triggered is not affected by the dialog display (other than by the focus events described above).
The bound components of the triggering page are however updated when a dialog is dismissed.
Data bindings
If a dialog page has bindings to the same part of the model as the current page in the application then special measures need to be taken to ensure that the data is displayed and saved in a consistent way. Take for example the following page which shows a dialog:
The calling page declaration
<Page class="org.formaria.test.Customer"> <Components> <Label x="154" y="136" w="79" h="20" style="Caption" content="Firstname:"/> <Edit name="firstnameText" x="241" y="136" w="238" h="20"/> <Button name="dlgButton" x="260" y="230" w="100" h="20" content="Open Dialog"/> </Components> <Events> <Event method="openDialog" target="dlgButton" type="ActionHandler"/> </Events> <Data> <Bind target="firstnameText" source="cust/firstname" output="cust/firstname"/> </Data> </Page>
And the popup dialog which reproduces some of the input is as follows:
The dialog page declaration
<Page class="org.formaria.test.CustDlg"> <Components> <Label x="10" y="10" w="80" h="20" content="Firstname:"/> <Edit x="100" y="10" w="100" h="20" name="firstnameText"/> <Button x="30" y="60" w="50" h="20" name="OKBtn" content="OK"/> <Button x="100" y="60" w="50" h="20" name="cancelBtn" content="Cancel"/> </Components> <Events> <Event method="okClick" target="OKBtn" type="ActionHandler"/> <Event method="cancelClick" target="cancelBtn" type="ActionHandler"/> </Events> <Data> <Bind target="firstnameText" source="cust/firstname" output="cust/firstname"/> </Data> </Page>
Both the customer and the dialog page have declared bindings for their respective
firstnameText
text components to the same path in the data model. This means that the
firstnameText
component in the main application needs to display the results of the dialog if OK was clicked. So the
Customer
class
openDialog
function should look like the following.
The openDialog function
public void openDialog() { saveBoundComponentValues(); Dialog dlg = (Dialog)pageMgr.loadPage( "CustDlg" ); dlg.pack(); dlg.showDialog( this ); }
The first line of this function makes a call to the
saveBoundComponentValues
function of the
Page
in order to persist all of the screen information to the data model. This ensures that when the the dialog is displayed it will be consistent with the customer page.
A similar situtation arises when the dialog is dismissed. Normally the dialog just disappears and you do not need to worry about the dialog's data. However if you are binding data as described above you will need to save the data when the dialog is dismissed and update the page that had displayed the dialog. The
CustDlg
class which subclasses the
Dialog
class follows.
The CustDlg class
public class CustDlg extends Dialog { private boolean okClicked = false; public void pageActivated() { okClicked = false; } public void okClick() { okClicked = true; closeDlg(); }</P> </TD> </TR> <TR> <TD ROWSPAN="1" COLSPAN="1"> <P> public void cancelClick() { closeDlg(); } public void saveBoundComponentValues() { if ( okClicked ) super.saveBoundComponentValues(); } }
When the OK button is clicked it is necessary to persist the bindings to the model. This is done by overloading the
saveBoundComponentValue
function and only calling the super function if the
okClicked
flag is true.
Fortunately the dialog class provides the
setSaveOnClose(true)
method to do exactly the above and saves you some code. The method causes the dialog to save its data and update the calling page if the OK button is used to dismiss the dialog. The saveOnClose flag is set to true by default so you do not need to modify the
openDialog
method.
The dialog still needs to know when the cancel button is clicked (assuming you have a cancel button on your dialog) and the method
cancelDlg
can be used to dismiss the dialog without saving the data. The modified page is as follows:
The dialog page with the calls to closeDlg and cancelDlg
<Page class="org.formaria.test.CustDlg"> <Components> <Label x="10" y="10" w="80" h="20" content="Firstname:"/> <Edit x="100" y="10" w="100" h="20" name="firstnameText"/> <Button x="30" y="60" w="50" h="20" name="OKBtn" content="OK"/> <Button x="100" y="60" w="50" h="20" name="cancelBtn" content="Cancel"/> </Components> <Events> <Event method="closeDlg" target="OKBtn" type="ActionHandler"/> <Event method="cancelDlg" target="cancelBtn" type="ActionHandler"/> </Events> <Data> <Bind target="firstnameText" source="cust/firstname" output="cust/firstname"/> </Data> </Page>
Now, since there is no need to set a special flag for the cancel event we can get rid of the rest of the custom code and just call the
closeDlg
method in response to the OK button click.
The dialog has one more button, the close button in the top right of the toolbar. This button is treated as the Cancel button and automatically dismisses the dialog without saving any data.
- Printer-friendly version
- Login or register to post comments