Custom JFace Dialog Creation

how-to
Dec 27, 20099 mins

Creation of Jface Dialog with no buttons at all

An article by Debadatta Mishra

Introduction

Eclipse editor provides many different features including many sorts of dialogs specific to requirements. In some dialog boxex, there are no default buttons including the close ‘X’ button. In this kind of dialog you will have better control over it. In case of normal dialog box there will be three default buttons. They are “OK”, “Cancel” and the close X button. At the time of development, sometimes it becomes difficult to handle these buttons for very specific requirements. In this article I will provide you a trick so that no default buttons will be visible in a dialog box .

Technicalities

In Eclipse plugin or RCP development, there are many ways you can create dialogs. However developers follow two ways of creation of dialogs. One is extending “org.eclipse.jface.dialogs.Dialog” and aonther is extending “org.eclipse.jface.dialogs.TitleAreaDialog”. I hope that you know the benefit of using the above dialogs. As per the dialog functionlites, Eclipse API provides many methods for rapid development. You have to override certain methods to achieve your requirements. First of all you have to override the method “setShellStyle()” method so that the default close X button will not be created in the top right most corner of the dialog. I have received many mails from the developers how to handle the X button. Of course there is a trick you can have control, I will explain in my next article. In the method “setShellStyle()”, you have to mention the shell style as “SWT.TITLE”. Besides while creating a dialog, two default buttons are created. They are “OK” and “Cancel”. It becomes necessary to create the buttons specific to your requirements and the buttons will have name like “Save”,”Close”,”Edit”,”Delete” etc. It is also possible to create the buttons by overriding the methods provided by Dialog class ,still it will be easier to create the independent buttons so that it will be easier for debugging and bug fixing. In order to eliminate the default “OK” and “Cancel” button, you have to override the method “createButton()” and return the value as null . Let us have a complete understanding in looking into the following piece of code.

Code for DialogWithNoButtonsAtAll.java


package com.core.plugin.dialog;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
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;

/**
 * This class is used to create a jface dialog box
 * with no default buttons. Run it to see the effect.
 * @author Debadatta Mishra(PIKU)
 *
 */
public final class DialogWithNoButtonsAtAll extends Dialog 
{
	/**
	 * Default constructor
	 * @param shell of type {@link Shell}
	 * @author Debadatta Mishra(PIKU)
	 */
	public DialogWithNoButtonsAtAll( Shell shell ) 
	{
		super( shell );
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.window.Window#setShellStyle(int)
	 */
	protected void setShellStyle(int arg0) 
	{
		//Use the following not to show the default close X button in the title bar
		super.setShellStyle(SWT.TITLE);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
	 */
	protected Control createDialogArea(Composite parent) 
	{
		/*
		 * Create the dialog area where you can place the UI components
		 */
		Composite composite = ( Composite )super.createDialogArea(parent);
		//Set the shell message
		composite.getShell().setText("A dialog box with no buttons at all press 'ESC' to close");
		try 
		{
			composite.setLayout(new FormLayout());
			{
				//Place all your UI Components
				/*
				 * I have created the dummy UI components
				 * so that you will feel comfortable
				 */
				//Create a Label
				createLabel(composite);
				//Create a Text field
				createTextField(composite);
				//Create a push button
				createButton(composite);
			}
		}
		catch (Exception e) 
		{
			e.printStackTrace();
		}
		//Set the size of the parent shell
		composite.getShell().setSize(300, 100);
		//Set the dialog position in the middle of the monitor
		setDialogLocation();
		return composite;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.dialogs.Dialog#createButton(org.eclipse.swt.widgets.Composite, int, java.lang.String, boolean)
	 */
	protected Button createButton(Composite arg0, int arg1, String arg2, boolean arg3) 
	{
		//Retrun null so that no default buttons like 'OK' and 'Cancel' will be created
		return null;
	}

	//~~ UI creation methods
	
	/**
	 * Method to create a Label
	 * @param composite of type {@link Composite}
	 * @author Debadatta Mishra(PIKU)
	 */
	private void createLabel( Composite composite )
	{
		Label label = new Label( composite , SWT.None );
		label.setText("Label 1");
		FormData lblData = new FormData();
		lblData.width = 40;
		lblData.height = 20;
		lblData.left =  new FormAttachment(0, 1000, 6);//x co-ordinate
		lblData.top =  new FormAttachment(0, 1000, 17);//y co-ordinate
		label.setLayoutData(lblData);
	}

	/**
	 * Method to create a text field
	 * @param composite of type {@link Composite}
	 * @author Debadatta Mishra(PIKU)
	 */
	private void createTextField( Composite composite )
	{
		Text text = new Text( composite , SWT.None );
		text.setText("Some text data");
		FormData txtData = new FormData();
		txtData.width = 100;
		txtData.height = 20;
		txtData.left = new FormAttachment(0,1000,50);//x co-ordinate
		txtData.top = new FormAttachment(0,1000,17);//y co-ordinate
		text.setLayoutData(txtData);
	}

	/**
	 * Method to create a push button
	 * @param composite of type {@link Composite}
	 * @author Debadatta Mishra(PIKU)
	 */
	private void createButton( Composite composite )
	{
		Button btn = new Button( composite , SWT.PUSH );
		btn.setText("Press to close");
		FormData btnData = new FormData();
		btnData.width = 90;
		btnData.height = 20;
		btnData.left = new FormAttachment(0,1000,100);//x co-ordinate
		btnData.top = new FormAttachment(0,1000,40);//y co-ordinate
		btn.setLayoutData(btnData);
		//Write listener for button
		btn.addSelectionListener( new SelectionAdapter()
		{
			public void widgetSelected(SelectionEvent se) 
			{
				close();
			}
		}
		);
	}

	//~~ Utility methods

	/**
	 * Method used to set the dialog in the centre of the monitor
	 * @author Debadatta Mishra(PIKU)
	 */
	private void setDialogLocation()
	{
		Rectangle monitorArea = getShell().getDisplay().getPrimaryMonitor().getBounds();
		Rectangle shellArea = getShell().getBounds();
		int x = monitorArea.x + (monitorArea.width - shellArea.width)/2;
		int y = monitorArea.y + (monitorArea.height - shellArea.height)/2;
		getShell().setLocation(x,y);
	}
}

Let us have look into the following test harness class to execute the above class.

Code for TestDialogWithNoButtonsAtAll.java


package com.core.plugin.test.dialog;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import com.core.plugin.dialog.DialogWithNoButtonsAtAll;

/**
 * A test harness class to test the dialog with no default buttons
 * @author Debadatta Mishra(PIKU)
 *
 */
public class TestDialogWithNoButtonsAtAll 
{
	public static void main(String[] args) 
	{
		final Display display = new Display ();
		final Shell shell = new Shell (display, SWT.BORDER);
		
		//Create a button in the blank shell
		Button openBtn = new Button( shell , SWT.PUSH );
		String dialogBtnMsg = "Open a new Dialog with no X button";
		openBtn.setText(dialogBtnMsg);
		openBtn.setBounds(10, 10, dialogBtnMsg.length()*8, 30);
		//Listener for the open Button
		openBtn.addSelectionListener( new SelectionAdapter()
		{
			public void widgetSelected(SelectionEvent arg0) 
			{
				new DialogWithNoButtonsAtAll( new Shell()).open();
			}
		}
		);
		
		//Create a close button
		Button closeBtn =  new Button( shell , SWT.PUSH );
		String closeBtnString = "Close shell";
		closeBtn.setText(closeBtnString);
		closeBtn.setBounds(10, 50, closeBtnString.length()*8, 30);
		//Listener for the close button
		closeBtn.addSelectionListener( new SelectionAdapter()
		{
			public void widgetSelected(SelectionEvent arg0) 
			{
				shell.dispose();
			}
		}
		);
		
		shell.setSize(400, 200);
		shell.open ();
		while (!shell.isDisposed ()) 
		{
			if (!display.readAndDispatch ()) display.sleep ();
		}
		display.dispose ();
	}
}

In the above case, the extending class is Dialog. Similarly we can make use TitleAreaDialog to have the similar effect. Let us a look into the class extending TitleAreaDialog class.

Code for TitleAreaWithNoButtonsAtAll.java


package com.core.plugin.dialog;

import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;

/**
 * This class is used to create a TitleAreaDialog
 * with no default buttons.
 * @author Debadatta Mishra(PIKU)
 *
 */
public class TitleAreaWithNoButtonsAtAll extends TitleAreaDialog 
{
	/**
	 * @param shell of type {@link Shell}
	 */
	public TitleAreaWithNoButtonsAtAll(Shell shell)
	{
		super(shell);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jface.window.Window#setShellStyle(int)
	 */
	protected void setShellStyle(int arg0) 
	{
		//Use the following so that no close X button will be created in the dialog
		super.setShellStyle(SWT.TITLE);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jface.dialogs.TitleAreaDialog#createDialogArea(org.eclipse.swt.widgets.Composite)
	 */
	protected Control createDialogArea(Composite composite) 
	{
		getShell().setText("A TitleArea dialog with no default buttons");
		/*
		 * Create your custome UI.
		 * Place all your UI components here
		 */
		return composite;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jface.dialogs.Dialog#createButton(org.eclipse.swt.widgets.Composite, int, java.lang.String, boolean)
	 */
	protected Button createButton(Composite arg0, int arg1, String arg2, boolean arg3) 
	{
		//Returns null so that no default buttons like "OK","Cancel" will be created
		return null;
	}
}

Let us look into the test harness class to execute the above class.

Code for TestTitleAreaWithNoButtonsAtAll


package com.core.plugin.test.dialog;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import com.core.plugin.dialog.TitleAreaWithNoButtonsAtAll;


/**
 * A Test harness class to test the TitleAreaDialog
 * with no buttons.
 * @author Debadatta Mishra(PIKU)
 *
 */
public class TestTitleAreaDialogWithNoButtonsAtAll 
{
	//Main method to execute
	public static void main(String[] args) 
	{
		final Display display = new Display ();
		final Shell shell = new Shell (display, SWT.BORDER);
		
		//Create a button in the blank shell
		Button openBtn = new Button( shell , SWT.PUSH );
		String dialogBtnMsg = "Open a new TitleArea Dialog with no X button";
		openBtn.setText(dialogBtnMsg);
		openBtn.setBounds(10, 10, dialogBtnMsg.length()*8, 30);
		//Listener for the open Button
		openBtn.addSelectionListener( new SelectionAdapter()
		{
			public void widgetSelected(SelectionEvent arg0) 
			{
				new TitleAreaWithNoButtonsAtAll(new Shell()).open();
			}
		}
		);
		
		//Create a close button
		Button closeBtn =  new Button( shell , SWT.PUSH );
		String closeBtnString = "Close shell";
		closeBtn.setText(closeBtnString);
		closeBtn.setBounds(10, 50, closeBtnString.length()*8, 30);
		//Listener for the close button
		closeBtn.addSelectionListener( new SelectionAdapter()
		{
			public void widgetSelected(SelectionEvent arg0) 
			{
				shell.dispose();
			}
		}
		);
		
		shell.setSize(400, 200);
		shell.open ();
		while (!shell.isDisposed ()) 
		{
			if (!display.readAndDispatch ()) display.sleep ();
		}
		display.dispose ();
	}

}

Assumptions

I assume that reader of this article has Exposure to eclipse plugin development Knowledge on Java language Knowledge on running programs in Eclipse editor

Test Case details

I have tested the above program in the following conditions. OS Name : Windows Vista Eclipse API : 3.2 Java : 1.6.0_16 Java Editor : Eclipse 3.2

Conclusion

I hope that you will enjoy my article. This article does not bear any commercial significance , it is only meant for learning and for novice developers. In case of any problem or errors , feel free to contact me in the email debadatta.mishra@gmail.com .