Archive

Posts Tagged ‘wizards’

JFace Wizard Explained – Enabling/Disabling Next, finish buttons

November 22, 2011 3 comments

This post assumes the reader has basic knowledge about creating jface wizards. To know about the basics refer here.

One of the most used member of the jface is the wizard. Almost in every rcp application this is used. I have quite a experience in wizard and I would like to post this for easy understanding for the people who are new to jface wizard.

As you might know wizard is commonly used for sequence of operations which require more than one input followed by their processing and finishing the process with the processed input.

Please  refer the flow chart below for the initial flow of wizard and wizard page creations.

One of the important thing which is in programmer’s control in wizard is the enabling/disabling of the buttons (back, next & finish) in the wizard.

As from the flow chart you can see when the wizard is created the wizard’s canFinish() method is called . if it is returning ‘false’ then finish button will be disabled else willl be enabled.

If we are not overriding the canFinish() method then by default the finish button will be enabled.

In most of the cases we should disable the finish button at the start and enable the next button for the current page based on some user selection.

Wizard provides an API to enable/disable finish button based on programmer’s preference.

‘setPageComplete(boolean) ‘ if it is set to true the finish get enabled disabled otherwise.

So , calling setPageComplete(false) in the wizard page(s) constructor will make the finish button to be disabled at the beginning of the wizard.

In the process of wizard user have to enable/disable “Next button alone” ,  so overriding canFlipToNextPage() in the wizard page  will help us to do the same. One important thing we have to note here is programmer has to explicitly call the “getWizard().getContainer().updateButtons()” to update the buttons.

Please refer to the below flow chart for updateButtons() actions. For better reading I have splitted the actions which is taking place in updateButtons() method in to two process.

Note: setPageComplete(Boolean) internally again calls the canFinish() method of the wizard . so if overided it is programmer’s responsibility to retrun true/false.

I am attaching sample code below.

Wizard Class:


import org.eclipse.jface.wizard.Wizard;

public class MyWizard extends Wizard {

FirstPage firstPage = null;
 SecondPage secondPage = null;

public MyWizard() {
 super();
 }

public void addPages()
 {
 firstPage = new FirstPage("First Page");
 addPage(firstPage);

secondPage = new SecondPage("secondpage");
 addPage(secondPage);
 }

/*
 * (non-Javadoc)
 * @see org.eclipse.jface.wizard.Wizard#performFinish()
 *
 * Varies according to user needs...
 */
 @Override
 public boolean performFinish() {
 return firstPage.isPageComplete() && secondPage.isPageComplete();
 }

}

Wizard Pages:


import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;

public class FirstPage extends WizardPage {

private CheckboxTableViewer checkboxTableViewer;
private boolean enableNext;

protected FirstPage(String pageName) {
super(pageName);
setTitle(pageName);
//        this is doing the trick
setPageComplete(false);
}

@Override
public void createControl(Composite arg0) {

Composite container = new Composite(arg0,SWT.NONE);
container.setLayout(new GridLayout());
container.setLayoutData(new GridData(SWT.FILL,SWT.FILL,true,true));

checkboxTableViewer = CheckboxTableViewer.newCheckList(container, SWT.FULL_SELECTION|SWT.BORDER);
checkboxTableViewer.getTable().setLinesVisible(true);
checkboxTableViewer.setContentProvider(new ArrayContentProvider());
checkboxTableViewer.setLabelProvider(new ITableLabelProvider() {

@Override
public void removeListener(ILabelProviderListener arg0) {

}

@Override
public boolean isLabelProperty(Object arg0, String arg1) {
return false;
}

@Override
public void dispose() {

}

@Override
public void addListener(ILabelProviderListener arg0) {

}

@Override
public String getColumnText(Object element, int columnIndex) {
return element.toString();
}

@Override
public Image getColumnImage(Object element, int columnIndex) {
return null;
}
});

checkboxTableViewer.setInput(new String[] {"one ","two","three"});

checkboxTableViewer.addCheckStateListener(new ICheckStateListener() {

@Override
public void checkStateChanged(CheckStateChangedEvent event) {
if(checkboxTableViewer.getCheckedElements().length > 0) {
enableNext = true;
}else {
enableNext = false;
}
checkStatus();

}

private void checkStatus() {
canFlipToNextPage();
//                explicit call
getWizard().getContainer().updateButtons();

}
});

setControl(container);

}

@Override
public IWizardPage getNextPage() {
IWizardPage[] pages = getWizard().getPages();
//        hard coding for this case . But this is bad..
return pages[1];
}

@Override
public boolean canFlipToNextPage() {
return enableNext;
}

@Override
public boolean isPageComplete() {
IWizardPage[] pages = getWizard().getPages();
//        hard coding for this case . But this is bad..
if(enableNext && pages[1].isPageComplete()) {
return true;
}
return false;
}

}

 


import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;

public class SecondPage extends WizardPage {

private Button button;

protected SecondPage(String pageName) {
super(pageName);
setTitle(pageName);
setPageComplete(false);
}

@Override
public void createControl(Composite arg0) {
Composite container = new Composite(arg0,SWT.NONE);
container.setLayout(new GridLayout());
container.setLayoutData(new GridData(SWT.FILL,SWT.FILL,true,true));

button = new Button(container, SWT.CHECK);
button.setText("check to finish the process");
button.setLayoutData(new GridData(SWT.FILL,SWT.FILL,true,false));

button.addMouseListener(new MouseAdapter() {
@Override
public void mouseDown(MouseEvent e) {
if (button.getSelection()) {
setPageComplete(false);

}else {
setPageComplete(true);
}
}
});

setControl(container);
}

}

Happy Coding.. 🙂

Categories: Jface Tags: , ,