Back to top

vogella training Training Books

Eclipse SWT and JFace Dialogs in Eclipse plug-in development - Tutorial

Lars Vogel

Version 2.2

23.02.2013

23.02.2012
Revision History
Revision 0.1 14.09.2010 Lars
Vogel
Created
Revision 0.2 - 2.2 29.11.2010 - 23.02.2013 Lars
Vogel
bug fixes and enhancements

Eclipse Dialog

This article describes the different kind of aialogs which can be used in Eclipse plug-in development. This tutorial is based on Eclipse 4.2 (Eclipse Juno).


Table of Contents

1. Dialogs in Eclipse
2. SWT System Dialogs
3. JFace Dialogs
3.1. MessageDialog and ErrorDialog
3.2. Own Dialog
3.3. JFace TitleAreaDialog
4. Selection Dialogs
5. Prerequisites for this tutorial
6. Tutorial: Using SWT Dialogs
7. Create a password dialog
8. Thank you
9. Questions and Discussion
10. Links and Literature
10.1. Eclipse Resources
10.2. Source Code
10.3. vogella Resources

1. Dialogs in Eclipse

Eclipse allows to use dialogs to prompt the user for additional information or provide the user with feedback. The Eclipse platform offers several standard dialogs via SWT and JFace.

2. SWT System Dialogs

SWT offers an API for the use of the native dialogs from the OS platform. The SWT dialogs are the following:

  • ColorDialog - for selecting a color

  • DirectoryDialog - for selecting a directory

  • FileDialog - for selecting a file

  • FontDialog - for selecting a font

  • MessageBox - for opening a message dialog

The following example shows how to use the MessageBox class to open a message dialog.

// create dialog with ok and cancel button and info icon
MessageBox dialog = 
  new MessageBox(shell, SWT.ICON_QUESTION | SWT.OK| SWT.CANCEL);
dialog.setText("My info");
dialog.setMessage("Do you really want to do this?");

# open dialog and wait for user selection
returnCode = dialog.open(); 

3. JFace Dialogs

3.1. MessageDialog and ErrorDialog

JFace contains additional dialogs which are more flexible than the SWT dialogs.

You can for example use the MessageDialog class which allows you to customize the Buttons which are used in the dialog. The following code demonstrates its usage.

// Customized MessageDialog with configured buttons
MessageDialog dialog = new MessageDialog(shell, "My Title", null,
    "My message", MessageDialog.ERROR, new String[] { "First",
  "Second", "Third" }, 0);
int result = dialog.open();
System.out.println(result); 

MessageDialog also provides static methods to open commonly used dialogs , e.g. an info or a warning dialog. The following code demonstrates the usage of these static methods.

//A few standard message dialogs
MessageDialog.openConfirm(shell, "Confirm", "Please confirm");
MessageDialog.openError(shell, "Error", "Error occured");
MessageDialog.openInformation(shell, "Info", "Info for you");
MessageDialog.openQuestion(shell, "Question", "Really, really?");
MessageDialog.openWarning(shell, "Warning", "I warn you"); 

Several of these dialogs return as status the user selection, e.g. the openConfirm() method returns true if the user selected the OK button. For example you can use the confirmation dialog via the following code.

boolean result = 
  MessageDialog.openConfirm(shell, "Confirm", "Please confirm");

if (result){
 // OK Button selected do something
} else {
 // Cancel Button selected do something
} 

JFace also provides the ErrorDialog class which allows you to report a Status object. Status objects are frequently used in Eclipse to report errors.

3.2. Own Dialog

The org.eclipse.jface.dialogs.Dialog class can be extended to create your own dialogs. This class creates a area in which you can place controls and add an OK and Cancel button to it.

Your class needs to implement the createDialogArea method. This method gets a Composite which expects to get a GridData object assigned as its layout data. Via the super.createDialogArea(parent) method call, you can get an Composite to which you can add your controls.

3.3. JFace TitleAreaDialog

You can also define your own Dialogs based on the TitleAreaDialog class.

TitleAreaDialog has a reserved space for providing feedback to the user. You can set the text in this space via the setMessage() and setErrorMessage() methods.

The following example shows a custom defined TitleAreaDialog.

package de.vogella.rcp.intro.dialogs.custom.dialogs;

import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public class MyDialog extends TitleAreaDialog {

  private Text firstNameText;
  private Text lastNameText;
  private String firstName;
  private String lastName;

  public MyDialog(Shell parentShell) {
    super(parentShell);
  }

  @Override
  public void create() {
    super.create();
    // Set the title
    setTitle("This is my first own dialog");
    // Set the message
    setMessage("This is a TitleAreaDialog", 
        IMessageProvider.INFORMATION);

  }

  @Override
  protected Control createDialogArea(Composite parent) {
    GridLayout layout = new GridLayout();
    layout.numColumns = 2;
    // layout.horizontalAlignment = GridData.FILL;
    parent.setLayout(layout);

    // The text fields will grow with the size of the dialog
    GridData gridData = new GridData();
    gridData.grabExcessHorizontalSpace = true;
    gridData.horizontalAlignment = GridData.FILL;

    Label label1 = new Label(parent, SWT.NONE);
    label1.setText("First Name");

    firstNameText = new Text(parent, SWT.BORDER);
    firstNameText.setLayoutData(gridData);
    
    Label label2 = new Label(parent, SWT.NONE);
    label2.setText("Last Name");
    // You should not re-use GridData
    gridData = new GridData();
    gridData.grabExcessHorizontalSpace = true;
    gridData.horizontalAlignment = GridData.FILL;
    lastNameText = new Text(parent, SWT.BORDER);
    lastNameText.setLayoutData(gridData);
    return parent;
  }

  @Override
  protected void createButtonsForButtonBar(Composite parent) {
    GridData gridData = new GridData();
    gridData.verticalAlignment = GridData.FILL;
    gridData.horizontalSpan = 3;
    gridData.grabExcessHorizontalSpace = true;
    gridData.grabExcessVerticalSpace = true;
    gridData.horizontalAlignment = SWT.CENTER;

    parent.setLayoutData(gridData);
    // Create Add button
    // Own method as we need to overview the SelectionAdapter
    createOkButton(parent, OK, "Add", true);
    // Add a SelectionListener

    // Create Cancel button
    Button cancelButton = 
        createButton(parent, CANCEL, "Cancel", false);
    // Add a SelectionListener
    cancelButton.addSelectionListener(new SelectionAdapter() {
      public void widgetSelected(SelectionEvent e) {
        setReturnCode(CANCEL);
        close();
      }
    });
  }

  protected Button createOkButton(Composite parent, int id, 
      String label,
      boolean defaultButton) {
    // increment the number of columns in the button bar
    ((GridLayout) parent.getLayout()).numColumns++;
    Button button = new Button(parent, SWT.PUSH);
    button.setText(label);
    button.setFont(JFaceResources.getDialogFont());
    button.setData(new Integer(id));
    button.addSelectionListener(new SelectionAdapter() {
      public void widgetSelected(SelectionEvent event) {
        if (isValidInput()) {
          okPressed();
        }
      }
    });
    if (defaultButton) {
      Shell shell = parent.getShell();
      if (shell != null) {
        shell.setDefaultButton(button);
      }
    }
    setButtonLayoutData(button);
    return button;
  }

  private boolean isValidInput() {
    boolean valid = true;
    if (firstNameText.getText().length() == 0) {
      setErrorMessage("Please maintain the first name");
      valid = false;
    }
    if (lastNameText.getText().length() == 0) {
      setErrorMessage("Please maintain the last name");
      valid = false;
    }
    return valid;
  }
  
  @Override
  protected boolean isResizable() {
    return true;
  }

  // Coyy textFields because the UI gets disposed
  // and the Text Fields are not accessible any more.
  private void saveInput() {
    firstName = firstNameText.getText();
    lastName = lastNameText.getText();
  }

  @Override
  protected void okPressed() {
    saveInput();
    super.okPressed();
  }

  public String getFirstName() {
    return firstName;
  }

  public String getLastName() {
    return lastName;
  }
} 

This Dialog can get opened via:

MyDialog dialog = new MyDialog(shell);
dialog.create();
if (dialog.open() == Window.OK) {
  System.out.println(dialog.getFirstName());
  System.out.println(dialog.getLastName());
} 

4. Selection Dialogs

Eclipse provides several standard selection Dialogs in Eclipse 3.x. In Eclipse 3.x you can directly use them, in Eclipse 4.x you may have to copy them into your plug-in and modify them slightly. I still list them here, so that you can use their coding as examples.

A release after Eclipse 4.2 might make the dialogs directly available again.

Here is a list of these Dialogs.

  • ElementListSelectionDialog

  • ListDialog

  • ElementTreeSelectionDialog

  • CheckTreeSelectionDialog

For example ElementListSelectionDialog allows you to select elements from a list where the dialog provides a filter for the elements.

ElementListSelectionDialog dialog = 
  new ElementListSelectionDialog(shell, new LabelProvider());
dialog.setElements(new String[] { "Linux", "Mac", "Windows" });
dialog.setTitle("Which operating system are you using");
// User pressed cancel
if (dialog.open() != Window.OK) {
    return false;
}
Object[] result = dialog.getResult(); 

5. Prerequisites for this tutorial

This tutorial assumes what you have basic understanding of development for the Eclipse platform. Please see Eclipse RCP Tutorial or Eclipse Plug-in Tutorial if you need any basic information.

6. Tutorial: Using SWT Dialogs

The following demonstrates how to use the SWT Dialogs in an Eclipse application. We will use a Button in the view to call the SWT Dialogs.

Create a new Eclipse plug-in project called "de.vogella.rcp.dialogs.swt" with one Part (View). Create the following composite.

package de.vogella.rcp.dialogs.swt;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.ColorDialog;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.FontDialog;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;

public class MyComposite extends Composite {

  public MyComposite(final Composite parent, int style) {
    super(parent, style);
    Button button = new Button(parent, SWT.PUSH);
    button.setText("Press me");
    button.addSelectionListener(new SelectionAdapter() {
      @Override
      public void widgetSelected(SelectionEvent e) {
        Shell shell = parent.getShell();
        openDialogs(shell);
      }
    });

  }

  private void openDialogs(Shell shell) {
    // File standard dialog
    FileDialog fileDialog = new FileDialog(shell);
    // Set the text
    fileDialog.setText("Select File");
    // Set filter on .txt files
    fileDialog.setFilterExtensions(new String[] { "*.txt" });
    // Put in a readable name for the filter
    fileDialog.setFilterNames(new String[] { "Textfiles(*.txt)" });
    // Open Dialog and save result of selection
    String selected = fileDialog.open();
    System.out.println(selected);

    // Directly standard selection
    DirectoryDialog dirDialog = new DirectoryDialog(shell);
    dirDialog.setText("Select your home directory");
    String selectedDir = dirDialog.open();
    System.out.println(selectedDir);

    // Select Font
    FontDialog fontDialog = new FontDialog(shell);
    fontDialog.setText("Select your favorite font");
    FontData selectedFont = fontDialog.open();
    System.out.println(selectedFont);

    // Select Color
    ColorDialog colorDialog = new ColorDialog(shell);
    colorDialog.setText("Select your favorite color");
    RGB selectedColor = colorDialog.open();
    System.out.println(selectedColor);

    // Message
    MessageBox messageDialog = new MessageBox(shell, SWT.ERROR);
    messageDialog.setText("Evil Error has happend");
    messageDialog.setMessage("This is fatal!!!");
    int returnCode = messageDialog.open();
    System.out.println(returnCode);

    // Message with ok and cancel button and info icon
    messageDialog = new MessageBox(shell, 
        SWT.ICON_QUESTION | 
        SWT.OK
        | SWT.CANCEL);
    messageDialog.setText("My info");
    messageDialog.setMessage("Do you really want to do this.");
    returnCode = messageDialog.open();
    System.out.println(returnCode);
  }

} 

In the method which creates your user interface, add this composite to your Part via:

new MyComposite(parent, SWT.NONE); 

Run the application. If you select your button the Dialogs will be displayed.

7. Create a password dialog

Create a new class called PasswordDialog which extends the Dialog class. This dialog should allow to enter a user name and a password.

Enter user credentials

package com.example.e4.rcp.todo.dialogs;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.layout.GridData;

public class PasswordDialog extends Dialog {
  private Text userText;
  private Text passwordText;
  private String user="";
  private String password="";

  
/** * Create the dialog. * * @param parentShell */
public PasswordDialog(Shell parentShell) { super(parentShell); }
/** * Create contents of the dialog. * * @param parent */
@Override protected Control createDialogArea(Composite parent) { Composite container = (Composite) super.createDialogArea(parent); GridLayout gl_container = new GridLayout(2, false); gl_container.marginRight = 5; gl_container.marginLeft = 10; container.setLayout(gl_container); Label lblUser = new Label(container, SWT.NONE); lblUser.setText("User:"); userText = new Text(container, SWT.BORDER); userText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); userText.setText(user); Label lblNewLabel = new Label(container, SWT.NONE); GridData gd_lblNewLabel = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1); gd_lblNewLabel.horizontalIndent = 1; lblNewLabel.setLayoutData(gd_lblNewLabel); lblNewLabel.setText("Password:"); passwordText = new Text(container, SWT.BORDER); passwordText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); passwordText.setText(password); return container; }
/** * Create contents of the button bar. * * @param parent */
@Override protected void createButtonsForButtonBar(Composite parent) { createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); }
/** * Return the initial size of the dialog. */
@Override protected Point getInitialSize() { return new Point(450, 300); } @Override protected void okPressed() { user = userText.getText(); password = passwordText.getText(); super.okPressed(); } public String getUser() { return user; } public void setUser(String user) { this.user = user; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }

To use the dialog in your application, create a menu entry (and a command with a handler) which allows you to open this dialog. The class associated with the handler should be called EnterCredentialsHandler.

package com.example.e4.rcp.todo.handlers;

import javax.inject.Inject;

import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.e4.core.di.extensions.Preference;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.widgets.Shell;

import com.example.e4.rcp.todo.dialogs.PasswordDialog;

public class EnterCredentialsHandler {
  
  @Execute
  public void execute(Shell shell) {
    PasswordDialog dialog = new PasswordDialog(shell);
    
    // Get the new values from the dialog
    if (dialog.open() == Window.OK) {
      //TODO do something with the values
    }
  }
  
} 

200_tutorial_swtdialogs.xml

8. Thank you

Please help me to support this article:

Flattr this

9. Questions and Discussion

Before posting questions, please see the vogella FAQ. If you have questions or find an error in this article please use the www.vogella.com Google Group. I have created a short list how to create good questions which might also help you.

10. Links and Literature

10.2. Source Code

Source Code of Examples

10.3. vogella Resources

vogella Training Android and Eclipse Training from the vogella team

Android Tutorial Introduction to Android Programming

GWT Tutorial Program in Java and compile to JavaScript and HTML

Eclipse RCP Tutorial Create native applications in Java

JUnit Tutorial Test your application

Git Tutorial Put everything you have under distributed version control system