Skip to content

Hello World in SWT JFace

Jochen Staerk edited this page Dec 21, 2015 · 2 revisions

This is a windows example of a small SWT application done in eclipse which embeds OpenOffice.org Writer

  1. download and install OpenOffice.org
  2. download, extract and start eclipse. This example is based on Eclipse SDK 3.2.1
Please note that the complete source code ready for copy&paste is available at the end of this article.

Table of Contents

Create a default JFace (SWT) Application

  1. Go to the workbench and create a new java project "hello NOA"
  2. right click on the project name in the workbench and choose Properties|Java Build Path|Libraries|Add external JARs and add
    1. /eclipse/plugins/org.eclipse.swt.win32.win32.x86_3.4.1.v3452b.jar
    2. /eclipse/plugins/org.eclipse.jface_3.4.2.M20090107-0800.jar
    3. /eclipse/plugins/org.eclipse.osgi_3.4.3.R34x_v20081215-1030.jar
    4. /eclipse/plugins/org.eclipse.core.commands_3.4.0.I20080509-2000.jar
    5. /eclipse/plugins/org.eclipse.equinox.common_3.4.0.v20080421-2006.jar
  3. create a new java package called "noaapp"
  4. create a new class "MainWindow" in that package which inherits from ApplicationWindow (Superclass org.eclipse.jface.window.ApplicationWindow). Check the checkbox to create the stubs for main in this class and the checkbox to create the stubs for "constructors from superclass".
  5. change the main method to
public static void main(String[] args) {
		// TODO Auto-generated method stub
		try {
			MainWindow window = new MainWindow(null);
			window.setBlockOnOpen(true);
			window.open();
			Display.getCurrent().dispose();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
  1. add an initial window size by overriding getInitialSize:
	protected Point getInitialSize() {
		return new Point(500, 375);
	}
  1. Organize imports (CTRL+Shift+O) to import the unit for the type Display and Point. For Point, please select the SWT point, not the AWT one.
  2. Select Run|Run, select java Application and click on the "New launch configuration" icon
  3. This is a complete JFace application. Run it: you should see a 500x375 pixel unnamed window without content.

Add OpenOffice.org Writer

OO Writer basics

This is where the fun starts.

  1. Download and extract NOA http://ubion.ion.ag/loesungen/004niceofficeaccess/
  2. add all NOA JARs in the lib directory to your list of external JARs
  3. make sure when your application is closed, all OOO.o-Documents are closed as well and the OfficeApplication gets deactivated
  4. add add a private IOfficeApplication officeApplication=null; and a private ITextDocument textDocument=null; member to the MainWindow class
  5. override createContents as follows:
	protected Control createContents(Composite parent) {
		Composite container = new Composite(parent, SWT.EMBEDDED);
		try {
			System.setProperty("sun.awt.noerasebackground", "true");
		} catch (NoSuchMethodError error) {
			System.out.println("Background not erased");
		}
		container.setLayout(new FillLayout());

		final Frame frame = SWT_AWT.new_Frame(container);

		final JPanel panel = new JPanel(new BorderLayout());
		panel.setVisible(true);
		frame.add(panel, BorderLayout.CENTER);
		try {
	
			HashMap<String, String> configuration = new HashMap<String, String>();
			configuration.put(IOfficeApplication.APPLICATION_HOME_KEY, "C:\\Programme\\OpenOffice.org 3");
			configuration.put(IOfficeApplication.APPLICATION_TYPE_KEY, IOfficeApplication.LOCAL_APPLICATION);
			try {
				officeApplication=OfficeApplicationRuntime.getApplication(configuration);
				officeApplication.setConfiguration(configuration);
				officeApplication.activate();
				
			} catch (OfficeApplicationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	

			IFrame officeFrame = officeApplication.getDesktopService().constructNewOfficeFrame(panel);
// create a new document
			IDocument document=officeApplication.getDocumentService().constructNewDocument(officeFrame, IDocument.WRITER, DocumentDescriptor.DEFAULT);
//			alternatively, you can load an existing document by using
//			IDocument document=officeApplication.getDocumentService().loadDocument(officeFrame,<url>);

// add a close listener so that OOo.o can be cleanly shut down
			ITextDocument textDocument=(ITextDocument) document;
			textDocument.getTextService().getText().setText("This is a text content for a SWT example with NOA.");
			// build the frame
			frame.validate();

			
//			Now it is time to disable two commands in the frame
// This comes from snippet14 
			officeFrame.disableDispatch(GlobalCommands.CLOSE_DOCUMENT);
			officeFrame.disableDispatch(GlobalCommands.QUIT_APPLICATION);
		} 
		catch (Throwable throwable) {
			throwable.printStackTrace();
		} 
		
		//
		return container;
	}

almost optional

  1. override window close as follows
	@Override
	public boolean close() {
		try {
			textDocument.close();
			officeApplication.deactivate();
		} catch (OfficeApplicationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return super.close();
	}

  1. Organize Imports (CTRL+Shift+O): choose SWT imports, the only allowed AWT import is Frame for the SWT/AWT bridge which has to be used.
  2. Handle keyfocus in Gnome Linux systems: add System.setProperty("sun.awt.xembedserver", "true");
  3. this application is based on the snippets 12, 14 and SnippetDocumentCloseListener

Referenced JARs

In SWT 3.3/NOA 2.0.9:

  • NOA JARs
    • ag.ion.noa_2.0.9.jar
    • bion_jurt-2.0.jar
    • bion_officebean-2.0.jar
    • ridl.jar
    • unoil.jar
    • juh.jar
  • Eclipse JARs
    • org.eclipse.core.commands_3.3.0.I20070605-0010.jar
    • org.eclipse.equinox.common_3.3.0.v20070426.jar
    • org.eclipse.jface_3.3.0.I20070606-0010.jar
    • org.eclipse.swt.win32.win32.x86_3.3.0.v3346.jar
    • org.eclipse.swt_3.3.0.v3346.jar

The complete source

  1. the complete Application should now look like this
import java.awt.BorderLayout;
import java.awt.Frame;
import java.util.HashMap;

import javax.swing.JPanel;

import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.awt.SWT_AWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

import ag.ion.bion.officelayer.application.IOfficeApplication;
import ag.ion.bion.officelayer.application.OfficeApplicationException;
import ag.ion.bion.officelayer.application.OfficeApplicationRuntime;
import ag.ion.bion.officelayer.desktop.GlobalCommands;
import ag.ion.bion.officelayer.desktop.IFrame;
import ag.ion.bion.officelayer.document.DocumentDescriptor;
import ag.ion.bion.officelayer.document.IDocument;
import ag.ion.bion.officelayer.text.ITextDocument;

public class MainWindow extends ApplicationWindow {
	private IOfficeApplication officeApplication=null;
	private ITextDocument textDocument=null;

	public MainWindow(Shell arg0) {
		super(arg0);
	}

	@Override
	public boolean close() {
		try {
			textDocument.close();
			officeApplication.deactivate();
		} catch (OfficeApplicationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return super.close();
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		try {
			MainWindow window = new MainWindow(null);
			window.setBlockOnOpen(true);
			window.open();
			Display.getCurrent().dispose();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	protected Point getInitialSize() {
		return new Point(500, 375);
	}
	
	protected Control createContents(Composite parent) {
		System.setProperty("sun.awt.xembedserver", "true");
		Composite container = new Composite(parent, SWT.EMBEDDED);
		try {
			System.setProperty("sun.awt.noerasebackground", "true");
		} catch (NoSuchMethodError error) {
			System.out.println("Background not erased");
		}
		container.setLayout(new FillLayout());

		final Frame frame = SWT_AWT.new_Frame(container);

		final JPanel panel = new JPanel(new BorderLayout());
		panel.setVisible(true);
		frame.add(panel, BorderLayout.CENTER);
		try {
	
			HashMap<String, String> configuration = new HashMap<String, String>();
			configuration.put(IOfficeApplication.APPLICATION_HOME_KEY, "C:\\Program Files\\OpenOffice.org 3");
			configuration.put(IOfficeApplication.APPLICATION_TYPE_KEY, IOfficeApplication.LOCAL_APPLICATION);
			try {
				officeApplication=OfficeApplicationRuntime.getApplication(configuration);
				officeApplication.setConfiguration(configuration);
				officeApplication.activate();
				
			} catch (OfficeApplicationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	

			IFrame officeFrame = officeApplication.getDesktopService().constructNewOfficeFrame(panel);
// create a new document
			IDocument document=officeApplication.getDocumentService().constructNewDocument(officeFrame, IDocument.WRITER, DocumentDescriptor.DEFAULT);
//			alternatively, you can load an existing document by using
//			IDocument document=officeApplication.getDocumentService().loadDocument(officeFrame,<url>);

// add a close listener so that OOo.o can be cleanly shut down
			textDocument=(ITextDocument) document;
			textDocument.getTextService().getText().setText("This is a text content for a SWT example with NOA.");
			
			// build the frame
			frame.validate();

			
//			Now it is time to disable two commands in the frame
// This comes from snippet14 
			officeFrame.disableDispatch(GlobalCommands.CLOSE_DOCUMENT);
			officeFrame.disableDispatch(GlobalCommands.QUIT_APPLICATION);
		} 
		catch (Throwable throwable) {
			throwable.printStackTrace();
		} 
		
		//
		return container;
	}
	private void createActions() {
	}



}

Screenshot

This is how it looks like in the end. Interestingly, the empty title bar is the only difference to a real OO.o writer. Plus you can now start adding functionality, buttons etc. around: of course you don#t need to use your Java application's full window for OO.o.

Screenshot of a simple embeeded writer in a SWT/JFace application