Hướng dẫn lập trình Eclipse RCP 4 cho người mới bắt đầu - Ứng dụng e4 Workbench
Công ty Vĩnh Cửu tuyển dụng lập trình viên Java

1- Giới thiệu

Tài liệu này được viết dựa trên:
  • Eclipse 4.5 (MARS)

  • Eclipse e4 RCP  (RCP 4)

Document History:
  • 27-08-2014: Based on Eclipse 4.4 LUNA + RCP 3.x
  • 10-07-2015: Update to Eclipse 4.5 MARS + Eclipse E4 RCP.

Chú ý:

Bạn có thể xem lập trình RCP 3.x tại:

2- Các cài đặt trước khi bắt đầu

2.1- Cài đặt Eclipse

Bạn cần có Eclipse phiên bản mới nhất. Hiện tại đang là Eclipse 4.5 (Mã hiệu MARS).
Theo tôi bạn lên download package: "Eclipse IDE for Java EE Developers". Các package chỉ khác nhau số lượng Plugin, cho các mục đích lập trình khác nhau. Trong quá trình lập trình có thể cài thêm các Plugin cho các mục đích khác

2.2- Cài đặt WindowBuilder

Cài đặt Plugin WindowBuilder, đây là 1 Plugin cho phép bạn thiết kế giao diện ứng dụng SWT bằng cách kéo thả rất tiện lợi.
Xem hướng dẫn cài đặt tại:

2.3- Cài đặt e4 Tools Developer Sources

Bạn có thể xem hướng dẫn cài đặt tại:

3- Tạo mới Java Workspace

Để lập trình ứng dụng RCP bạn nên tạo mới một Java Workspace:
  • File/Switch Workspace/Other..
Nhập vào:
  • F:\ECLIPSE_TUTORIAL\RCP

4- Tạo Eclipse 4 RCP Project rỗng

Trong tài liệu này tôi sẽ hướng dẫn bạn xây dựng một ứng dụng RCP từ khi bắt đầu (Không làm theo template có sẵn), vì vậy tôi sẽ tạo ra một ứng dụng Eclipse RCP rỗng.
Trên Eclipse chọn: File/New/Other...
  1. Check chọn trên (1)
  2. Trên vùng (2) chọn "Yes" để Eclipse tạo ra RCP Project (Chạy trên Desktop) , ngược lại nó sẽ tạo ra RAP Project (Chạy trên Web).
Lựa chọn "Eclipse 4 RCP Application"
Nhập vào:
  • Java package name: org.o7planning.tutorial.rcp
Đây là hình ảnh Project được tại ra:

Chạy thử ứng dụng:

Nhấn phải chuột vào EclipseRCPTutorial.product chọn Run As/Eclipse Application

5- Cấu trúc của ứng dụng Eclipse 4 RCP rỗng

Ứng dụng Eclipse 4 RCP rỗng đã được Eclipse tạo ra, hãy xem cấu trúc của nó. Mở file Application.e4xmi:
Thay đổi tiêu đề của ứng dụng thành "Eclipse E4 RCP Application" như hình minh họa dưới đây.
Và chạy lại ứng dụng:

6- Handler và Command

RCP Framework xây dựng sẵn rất nhiều Command, chẳng hạn 4 command có ID dưới đây:
  1. org.eclipse.ui.file.exit
    • Lệnh thoát ra khỏi ứng dụng
  2. org.eclipse.ui.file.open
    • Lệnh mở file.
  3. org.eclipse.ui.file.save
    • Lệnh save editor
  4. org.eclipse.ui.help.aboutAction
    • Lệnh mở ra cửa sổ About.

Bạn có thể xem thêm danh sách các command được xây dựng sẵn của RCP framework tại:

Tạo mới một Command có tên quiteCommand, gọi tới lệnh thoát khỏi ứng dụng đã được xây dựng sẵn của RCP Framework.
Tương tự chúng ta tạo tiếp 3 Command khác:
Lệnh gọi editor mở file đã được chọn.
  • ID: org.eclipse.ui.file.open
  • Name: openCommand
Thực hiện lệnh save nội dung trên Editor.
  • ID: org.eclipse.ui.file.save
  • Name: saveCommand
AboutCommand:
  • ID: org.eclipse.ui.help.aboutAction
  • Name: aboutCommand
Handler là các class sử lý cho các lệnh (command) của Menu hoặc Toolbar. Khi bạn click vào MenuItem hoặc ToolItem có nghĩa là gọi thực thi một Command, trước khi Command được thực thi Handler sẽ được thực thi trước, bạn có thể hủy (cancel) việc Command được thực thi trong Handler.

Handler là các class mà khi được thực thi nó sẽ thực thi các nhiệm vụ được viết trong method có chú thích bởi @Execute.

Tôi sẽ tạo ra 4 class Handler:
AboutHandler.java
package org.o7planning.tutorial.rcp.handler;

import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Shell;

public class AboutHandler {
   
   @Execute
   public void execute(Shell shell) {
       MessageDialog.openInformation(shell, "About", "Eclipse 4 RCP Application");
   }
}
OpenHandler.java
package org.o7planning.tutorial.rcp.handler;

import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;

public class OpenHandler {

   @Execute
   public void execute(Shell shell){
       FileDialog dialog = new FileDialog(shell);
       dialog.open();
   }
}
QuitHandler.java
package org.o7planning.tutorial.rcp.handler;

import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.e4.ui.workbench.IWorkbench;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Shell;


public class QuitHandler {
   @Execute
   public void execute(IWorkbench workbench, Shell shell){
       if (MessageDialog.openConfirm(shell, "Confirmation",
               "Do you want to exit?")) {
           workbench.close();
       }
   }
}
SaveHandler.java
package org.o7planning.tutorial.rcp.handler;

import org.eclipse.e4.core.di.annotations.CanExecute;
import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.e4.ui.workbench.modeling.EPartService;

public class SaveHandler {

   @CanExecute
   public boolean canExecute(EPartService partService) {
       if (partService != null) {
           return !partService.getDirtyParts().isEmpty();
       }
       return false;
   }

   @Execute
   public void execute(EPartService partService) {
       partService.saveAll(false);
   }
}

Khai báo các class Handler với ứng dụng.

Khai báo một Handler với Application bạn phải khai báo ID, Handler class và Command.

Ví dụ người dùng đóng ứng dụng bằng cách click vào menuItem Exit, menuItem này gắn với quiteCommand, QuiteHandler là class sử lý cho command này (Như khai báo ở trên), class QuiteHandler sẽ hỏi người dùng có thực muốn đóng ứng dụng không, nếu có Command quiteCommand sẽ được thực thi.
Tương tự khai báo các Handler khác.

7- Khai báo Menus

Tạo menu chính (Main menu) của ứng dụng
Nhập vào ID của Main Menu, nó bắt buộc phải là: menu:org.eclipse.ui.main.menu
Thêm 3 menu con:
  • File, Function, Help
Khai báo các menu con cho menu File.
  • Open
  • Save
  • Exit
Bạn có thể chạy lại ứng dụng của mình:

8- Tạo Toolbar

Tạo Main Toolbar, với ID:
  • ID: toolbar:org.eclipse.ui.main.toolbar
Thêm vào 2 Toolitem: open & save
Chạy lại ứng dụng của bạn:

9- Part

SamplePart.java
/*******************************************************************************
 * Copyright (c) 2010 - 2013 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Lars Vogel <lars.Vogel@gmail.com> - Bug 419770
 *******************************************************************************/
package org.o7planning.tutorial.rcp.part;

import javax.annotation.PostConstruct;
import javax.inject.Inject;

import org.eclipse.e4.ui.di.Focus;
import org.eclipse.e4.ui.di.Persist;
import org.eclipse.e4.ui.model.application.ui.MDirtyable;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;

public class SamplePart {

    private Text txtInput;
    private TableViewer tableViewer;

    @Inject
    private MDirtyable dirty;

    @PostConstruct
    public void createComposite(Composite parent) {
        parent.setLayout(new GridLayout(1, false));

        txtInput = new Text(parent, SWT.BORDER);
        txtInput.setMessage("Enter text to mark part as dirty");
        txtInput.addModifyListener(new ModifyListener() {
            @Override
            public void modifyText(ModifyEvent e) {
                dirty.setDirty(true);
            }
        });
        txtInput.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        tableViewer = new TableViewer(parent);

        tableViewer.add("Sample item 1");
        tableViewer.add("Sample item 2");
        tableViewer.add("Sample item 3");
        tableViewer.add("Sample item 4");
        tableViewer.add("Sample item 5");
        tableViewer.getTable().setLayoutData(new GridData(GridData.FILL_BOTH));
    }

    @Focus
    public void setFocus() {
        tableViewer.getTable().setFocus();
    }

    @Persist
    public void save() {
        dirty.setDirty(false);
    }
}
Thêm mới PerspectiveStack. Đây là một ngăn xếp (Stack) chứa các khung nhìn (Perspective).
Thêm mới khung nhìn (Perspective):
Chạy lại ứng dụng:
Các thay đổi trên Part có thể làm nút SAVE sáng lên.