Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » JFace » WizardDialog, WizardPage Back, Next, Finish, Cancel Event Hooks
WizardDialog, WizardPage Back, Next, Finish, Cancel Event Hooks [message #12997] Tue, 09 June 2009 05:43 Go to next message
venkataramana m is currently offline venkataramana m
Messages: 86
Registered: July 2009
Member
At times, we would like to validate certain user inputs on a particular
wizard page when next, finish etc., are clicked. JFace WizardDialog seems
to capture those events in backPressed, nextPressed etc., But one needs to
handle the events locally in a page instead of the wizard dialog. So the
existing WizardDialog and WizardPage have been extended to facilitate
this. So in every subclass of WizardPage, one could implement the
necessary validations in nextPressed, finishPressed, cancelPressed etc.,

Check the code below.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
package yourpackage;

import org.eclipse.jface.dialogs.IPageChangedListener;
import org.eclipse.jface.dialogs.PageChangedEvent;
import org.eclipse.jface.wizard.IWizard;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.widgets.Shell;

/**
* This class specializes WizardDialog for some common requirements like
...
* 1. When NEXT, BACK, FINISH buttons are pressed, current active page
should
* be notified before showing the next page. Though those buttons can be
disabled/
* enabled in the modification listeners of the page controls but that is
expensive
* to do incase of repository centric ui.
* So the backPressed, nextPressed, finishPressed events are propagated to
* the current active page as well so that page can validate its input.
*
* Clients needs not subclass this dialog-class. It may be rarely required.
*/
public class ExWizardDialog extends WizardDialog implements
IPageChangedListener
{
public ExWizardDialog(Shell parentShell, IWizard newWizard)
{
super(parentShell, newWizard);
addPageChangedListener(this);
}

protected void backPressed()
{
IWizardPage currentActivePage = getCurrentPage();
ASSERTPageIsExWizardPage(currentActivePage);

/* notify current page if it wants to do any validation on input */
if( !((ExWizardPage)currentActivePage).backPressed() ) return;

/* delegate backPressed processing to super */
super.backPressed();
}

protected void nextPressed()
{
IWizardPage currentActivePage = getCurrentPage();
ASSERTPageIsExWizardPage(currentActivePage);

/* notify current page if it wants to do any validation on input */
if( !((ExWizardPage)currentActivePage).nextPressed() ) return;

/* delegate nextPressed processing to super */
super.nextPressed();
}

protected void finishPressed()
{
IWizardPage currentActivePage = getCurrentPage();
ASSERTPageIsExWizardPage(currentActivePage);

/* notify current page if it wants to do any validation on input */
if( !((ExWizardPage)currentActivePage).finishPressed() ) return;

/* delegate finishPressed processing to super */
super.finishPressed();
}

private void ASSERTPageIsExWizardPage(IWizardPage page) throws
IllegalArgumentException
{
if( page == null )
throw new IllegalArgumentException("Internal Error: Null page referred
in ExWizardDialog");

if( !(page instanceof ExWizardPage) )
throw new IllegalArgumentException("Internal Error: Page extending from
ExWizardPage can only be open with ExWizardDialog");
}


protected void cancelPressed()
{
IWizardPage currentActivePage = getCurrentPage();
ASSERTPageIsExWizardPage(currentActivePage);

/* notify current page if it wants to do any validation on input */
if( !((ExWizardPage)currentActivePage).cancelPressed() ) return;

/* delegate cancelPressed processing to super */
super.cancelPressed();
}

public void pageChanged(PageChangedEvent event)
{
IWizardPage page = (IWizardPage)event.getSelectedPage();
ASSERTPageIsExWizardPage(page);

/* notify page it has been activated */
((ExWizardPage)page).pageActivated();
}
}

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

package yourpackage;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;

/**
* This class specializes WizardPage for some common requirements like ...
* 1. When NEXT, BACK, FINISH buttons are pressed, current active page
should
* be notified before showing the next page. Though those buttons can be
disabled/
* enabled in the modification listeners of the page controls but that is
expensive
* to do incase of repository centric ui.
* So the backPressed, nextPressed, finishPressed events in WizardDialog
are propagated
* to the current active page as well so that page can validate its input.
*
* 2. Automates creating page control. A composite with standard dialog
margin/space settings
* and GridLayout is created.
*/
public abstract class ExWizardPage extends WizardPage
{
/**
* Font metrics to use for determining pixel sizes.
*/
private FontMetrics m_fontMetrics = null;

protected ExWizardPage(String pageName) {
super(pageName);
}

protected ExWizardPage(String pageName, String title, ImageDescriptor
titleImage) {
super(pageName, title, titleImage);
}

/*public void createControl(Composite parent)
{
Composite pageComposite = new Composite(parent, SWT.NONE);
setControl(pageComposite);
initializeDialogUnits(pageComposite);

set layout for page composite
GridLayout layout = new GridLayout();
setStandardDialogMarginAndSpacing(layout);
pageComposite.setLayout(layout);

create page contents
createPageContents(pageComposite);

set dialog font to composite and all of its children
Dialog.applyDialogFont(pageComposite);
}*/

protected void setStandardDialogMarginAndSpacing(GridLayout layout)
{
layout.marginWidth = Dialog.convertHorizontalDLUsToPixels(m_fontMetrics,
IDialogConstants.HORIZONTAL_MARGIN);
layout.marginHeight = Dialog.convertVerticalDLUsToPixels(m_fontMetrics,
IDialogConstants.VERTICAL_MARGIN);
layout.horizontalSpacing =
Dialog.convertHorizontalDLUsToPixels(m_fontMetrics,
IDialogConstants.HORIZONTAL_SPACING);
layout.verticalSpacing =
Dialog.convertVerticalDLUsToPixels(m_fontMetrics,
IDialogConstants.VERTICAL_SPACING);
}

protected void initializeDialogUnits(Control control) {
// Compute and store a font metric
GC gc = new GC(control);
gc.setFont(JFaceResources.getDialogFont());
m_fontMetrics = gc.getFontMetrics();
gc.dispose();
}

abstract protected void createPageContents(Composite pageComposite);

abstract protected void pageActivated();

/**
* Clients can validate current active page here before moving to
previous page
* @return TODO
*/
protected boolean backPressed() { return true; }

/**
* Clients can validate current active page here before moving to next
page
* @return TODO
*/
protected boolean nextPressed() { return true; }

/**
* Clients can validate current active page here before finishing
* @return TODO
*/
protected boolean finishPressed() { return true; }


/**
* Clients can validate current active page here before cancelling
* @return TODO
*/
protected boolean cancelPressed() { return true; }
}
Re: WizardDialog, WizardPage Back, Next, Finish, Cancel Event Hooks [message #771939 is a reply to message #12997] Wed, 28 December 2011 10:37 Go to previous message
Lukas Olbrich is currently offline Lukas Olbrich
Messages: 17
Registered: October 2010
Junior Member
Hi venkataramana m,
thanks for this solution. This looks good although like a lot to do. Wink.
Just in case anyone (like me for example) stumbles upon this page searching for a way to be notified about a page change within a wizard, there is sth. less extensive available:

In most cases a WizardDialog is used as a container for any kind of Wizard. This WizardDialog implements IWizardContainer2 and IPageChangeProvider. The latter provides methods to hook listeners. The WizardContainer can always be retrieved from any WizardPage via getContainer().
Thus, a simpler solution might be this:
@Override
public void createControl(final Composite parent) {
  final IWizardContainer container = this.getContainer();
  if (container instanceof IPageChangeProvider) {
    ((IPageChangeProvider)container).addPageChangedListener(this);
  }
...
}

Surely, the WizardPage would have to implement IPageChangeListener.

Cheers,
Lukas

[Updated on: Wed, 28 December 2011 10:43]

Report message to a moderator

Previous Topic:Should documentation for CellLabelProvider mention ColumnViewerToolTipSupport?
Next Topic:TableViewer.setInput is not setting data right
Goto Forum:
  


Current Time: Tue Jul 22 23:50:44 EDT 2014

Powered by FUDForum. Page generated in 0.02104 seconds