Eclipse Plugins Exposed, Part 3: Customizing a Wizard
Pages: 1, 2, 3, 4, 5, 6
In this method, we're adding one new page, named
InvokatronWizardPage2, which we'll write soon. Next are
methods that will execute when the user presses the Finish button
on the wizard:
public boolean performFinish() {
//First save all the page data as variables.
final String containerName =
page.getContainerName();
final String fileName =
page.getFileName();
final InvokatronDocument properties =
new InvokatronDocument();
properties.setProperty(
InvokatronDocument.PACKAGE,
page2.getPackage());
properties.setProperty(
InvokatronDocument.SUPERCLASS,
page2.getSuperclass());
properties.setProperty(
InvokatronDocument.INTERFACES,
page2.getInterfaces());
//Now invoke the finish method.
IRunnableWithProgress op =
new IRunnableWithProgress() {
public void run(
IProgressMonitor monitor)
throws InvocationTargetException {
try {
doFinish(
containerName,
fileName,
properties,
monitor);
} catch (CoreException e) {
throw new InvocationTargetException(e);
} finally {
monitor.done();
}
}
};
try {
getContainer().run(true, false, op);
} catch (InterruptedException e) {
return false;
} catch (InvocationTargetException e) {
Throwable realException =
e.getTargetException();
MessageDialog.openError(
getShell(),
"Error",
realException.getMessage());
return false;
}
return true;
}
Here we have a background task to do the saving of the data. The
background task is executed by the wizard's container (the Eclipse
workbench) and must implement the
IRunnableWithProgress interface, containing a sole
run() method. The IProgressMonitor that
is passed in allows reporting the progress of the task, as we'll see
next. The real data-saving work is in a helper method,
doFinish():
private void doFinish(
String containerName,
String fileName,
Properties properties,
IProgressMonitor monitor)
throws CoreException {
// create a sample file
monitor.beginTask("Creating " + fileName, 2);
IWorkspaceRoot root = ResourcesPlugin.
getWorkspace().getRoot();
IResource resource = root.findMember(
new Path(containerName));
if (!resource.exists() ||
!(resource instanceof IContainer)) {
throwCoreException("Container \"" +
containerName +
"\" does not exist.");
}
IContainer container =
(IContainer)resource;
final IFile iFile = container.getFile(
new Path(fileName));
final File file =
iFile.getLocation().toFile();
try {
OutputStream os =
new FileOutputStream(file, false);
properties.store(os, null);
os.close();
} catch (IOException e) {
e.printStackTrace();
throwCoreException(
"Error writing to file " +
file.toString());
}
//Make sure the project is refreshed
//as the file was created outside the
//Eclipse API.
container.refreshLocal(
IResource.DEPTH_INFINITE, monitor);
monitor.worked(1);
monitor.setTaskName(
"Opening file for editing...");
getShell().getDisplay().asyncExec(
new Runnable() {
public void run() {
IWorkbenchPage page =
PlatformUI.getWorkbench().
getActiveWorkbenchWindow().
getActivePage();
try {
IDE.openEditor(
page,
iFile,
true);
} catch (PartInitException e) {
}
}
});
monitor.worked(1);
}
Here we execute a lot of work:
- We retrieve the location (as Eclipse's
IFileclass) of the file we want to save. - We also get the
Fileequivalent of this. - We save the properties to this location.
- We then ask the Eclipse workbench to refresh the project, so that the new file can be displayed.
- We finally schedule a task to be executed in the future. This task involves opening the new file in an editor.
- Throughout this work, we keep the user informed of the progress
by calling methods of the
IProgressMonitorobject passed as a parameter.
The last method is a helper method to display error messages in the wizard if the file saving failed:
private void throwCoreException(
String message) throws CoreException {
IStatus status =
new Status(
IStatus.ERROR,
"Invokatron",
IStatus.OK,
message,
null);
throw new CoreException(status);
}
}
A CoreException is caught by the wizard, and the
Status object it contains is then displayed for the
user to see. The wizard won't be closed.