Hướng dẫn lập trình Eclipse RCP 3 cho người mới bắt đầu - Ứng dụng 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.4 (LUNA)  (or Eclipse 4.5 MARS create RCP 3 application, not Eclipse e4 RCP)

  • RCP 3

History:
  • 27-08-2014: Eclipse 4.4 LUNA + RCP3

Chú ý:

Phiên bản hiện thời của Eclipse RCP là 4.0, bạn có thể xem hướng dẫn tại:

2- Các cái cần thiết trước khi bắt đầu.

Bạn cần có Eclipse phiên bản mới nhất. Hiện tại đang là Eclipse 4.4 (Mã hiệu LUNA).
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.
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:
Cài đặt RCP Components.

3- RCP là gì và làm được gì

RCP (Rich Client Platform): Là một Platform nó được viết trên SWT, SWT vốn là thư viện lập trình các ứng dụng Desktop. RCP cung cấp một nền tảng giúp bạn làm được các ứng dụng có cấu trúc chẳng hạn giống Eclipse IDE.

Tôi có so sánh và phân tích các đặc điểm giữa các công nghệ:

  • RCP (SWT, RCP Workbench) - Chạy trên Desktop
  • RAP (Basic, RAP Workbench) - Chạy trên Web

Tại URL dưới đây, bạn có thể xem để có cái nhìn tổng quát.

RCP cho phép lập trình một ứng dụng Workbench có giao diện giống với giao diện của Eclipse IDE. Lập trình các Plugin tích hợp vào Eclipse IDE.

 
Để tạo một ứng dụng Desktop sử dụng SWT. Trên Eclipse chúng ta sẽ tạo một RCP Plugin Project. Bạn có 2 lựa chọn.
  • Chỉ sử dụng các tính năng của SWT
  • Sử dụng nền tảng cung cấp bởi RCP để lập trình ứng dụng RCP Workbench.

Bạn có thể xem hướng dẫn lập trình SWT tại đây:

4- Tạo Project

Trước hết bạn phải tạo một Workspace mới để bắt đầu:
Trên Eclipse chọn: File/Switch Workspace/Other...
Nhập vào thư mục workspace:
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).
Đây là hình ảnh Project được tại ra:

5- Chạy thử project RCP

Chúng ta sẽ chạy thử Project Hello RCP này ngay sau khi nó vừa được tạo ra.
Nhấn phải chuột vào Project: RCPWorkbenchTutorial chọn RunAs/Eclipse Application
Kết quả:

6- Cấu trúc ứng dụng RCP và cấu hình RCP

Đây là hình ảnh các class được mặc định tạo ra khi bạn tạo Project RCP từ template "Hello RCP":

Cấu hình ứng dụng:

Thay đổi code trong class ApplicationWorkbenchWindowAdvisor để đảm bảo thanh Coolbar, PerspectiveBar,.. sẽ được hiển thị trên Workbench:
  • ApplicationWorkbenchWindowAdvisor.java
package org.o7planning.tutorial.rcp;

import org.eclipse.swt.graphics.Point;
import org.eclipse.ui.application.ActionBarAdvisor;
import org.eclipse.ui.application.IActionBarConfigurer;
import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
import org.eclipse.ui.application.WorkbenchWindowAdvisor;

public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {

    public ApplicationWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) {
        super(configurer);
    }

    public ActionBarAdvisor createActionBarAdvisor(IActionBarConfigurer configurer) {
        return new ApplicationActionBarAdvisor(configurer);
    }
    
    public void preWindowOpen() {
        IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
        configurer.setInitialSize(new Point(400, 300));
        
        // Show MenuBar
        configurer.setShowMenuBar(true);
        // Show CoolBar.
        configurer.setShowCoolBar(true);
        // Show Status Line.
        configurer.setShowStatusLine(true);
        // Show PerspectiveBar
        configurer.setShowPerspectiveBar(true);
        // Show FastViewBars
        configurer.setShowFastViewBars(true);
        // Show ProgressIndicator
        configurer.setShowProgressIndicator(true);
        
        configurer.setTitle("Hello RCP"); //$NON-NLS-1$
    }
}
Chạy lại ứng dụng RCP:

7- Project Target Component

RCP là một Platform nó được xây dựng trên:
  • SWT
  • JFace
  • RCP Component.
Việc tạo một file "Target Define" là cần thiết để chủ động khai báo các thành phần cần dùng, và môi trường chạy cho ứng dụng RCP. Bạn cũng có thể sử dụng thêm các Component khác chẳng hạn như Nebula cho ứng dụng RCP của bạn, chỉ cần khai báo vào file "Target Define".

Tạo một Project java thông thường, để khai báo file "Target Define" trong đó.

Trước hết khai báo vị trí các thư viện SWT vốn có sẵn trên thư mục của Eclipse.
Tiếp theo khai báo thêm "RCP Target Component". Nó chính là các thành phần thư viện của RCP.
Nhập vào:
  • Name: RCP Target Component
  • Location: http://download.eclipse.org/eclipse/updates/4.4/
Nhấn vào "Set As Target Component", các thư viện đó sẽ là môi trường chạy cho ứng dụng RCP.

Bạn cũng có thể khai báo thêm các thư viện khác như Nebula, ... vào Target Component.
Xem thêm các Widget Nabula tại:

8- Tạo một vài Command sử dụng trong ứng dụng

Command là một lệnh, bạn có thể tạo các class Command để điều khiển một sự kiện nào đó chẳng hạn:
  • Mở file
  • Thoát khỏi ứng dụng
  • Mở AboutDialog
  • ....
Mỗi Command sẽ được đăng ký với một ID nào đó. Và MenuItem, hoặc ToolItem sẽ gọi tới lên thông qua ID.
  • AboutDialog.java

package org.o7planning.tutorial.rcp.dialog;

import org.eclipse.swt.SWT;

public class AboutDialog extends Dialog {

    protected Object result;
    protected Shell shlAbout;

    /**
     * Create the dialog.
     * @param parent
     * @param style
     */
    public AboutDialog(Shell parent, int style) {
        super(parent, style);
        setText("SWT Dialog");  
    }

    /**
     * Open the dialog.
     * @return the result
     */
    public Object open() {
        createContents();
        shlAbout.open();
        shlAbout.layout();
        Display display = getParent().getDisplay();
        while (!shlAbout.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
        return result;
    }

    /**
     * Create contents of the dialog.
     */
    private void createContents() {
        shlAbout = new Shell(getParent(), getStyle());
        shlAbout.setSize(418, 145);
        shlAbout.setText("About");
        shlAbout.setLayout(new GridLayout(1, false));
        
        Label lblNewLabel = new Label(shlAbout, SWT.NONE);
        lblNewLabel.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true, 1, 1));
        lblNewLabel.setText("RCP Tutorial");

    }

}
Tạo Extension Point:
  • org.eclipse.ui.commands

Tiếp theo chúng ta sẽ tạo class Command có ID:

  • org.o7planning.tutorial.rcp.cmd.about
Nhập vào:
  • id: org.o7planning.tutorial.rcp.cmd.about
  • defaultHandler: org.o7planning.tutorial.rcp.cmd.AboutCommand
Click vào link "defaultHandler" để tạo class.
Bạn nên viết AboutCommand extends từ class:
  • org.eclipse.core.commands.AbstractHandler.
  • AboutCommand.java
package org.o7planning.tutorial.rcp.cmd;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.handlers.HandlerUtil;
import org.o7planning.tutorial.rcp.dialog.AboutDialog;

public class AboutCommand extends AbstractHandler {

   @Override
   public Object execute(ExecutionEvent event) throws ExecutionException {
       Shell shell = HandlerUtil.getActiveWorkbenchWindow(event).getShell();
       AboutDialog dialog = new AboutDialog(shell, SWT.DIALOG_TRIM
               | SWT.APPLICATION_MODAL);
       dialog.open();
       return null;
   }

}

9- Thiết kế giao diện

9.1- Giao diện

Dưới đây là hình ảnh Workbench mà chúng ta sẽ thiết kế.

9.2- Menu

Chúng ta sẽ thiết kế Menu như hình minh họa dưới đây:
Nhập vào:
  • locationURI:  menu:org.eclipse.ui.main.menu

menu:org.eclipse.ui.main.menu ==> là ID xác định vị trí của Menu, nó là một hằng số có sẵn của RCP workbench.  Bạn cũng có thể tự tạo ra các locationURI để định nghĩa vị trí hiển thị MENU.

Tiếp theo tạo Menu "File".
Và tiếp theo thêm Command "Exit" vào Menu "File".
Nhập vào Command ID:
  • org.eclipse.ui.file.exit
Đây là một Command định nghĩa  sẵn trong RCP Platform, nó là lệnh thoát ra khỏi ứng dụng workbench.
Tương tự vậy chúng ta tạo tiếp Menu "Help".
Và tạo Command "About" con của Menu "Help".
Nhập vào ID của command sẽ được gọi đến:
  • org.o7planning.tutorial.rcp.cmd.about

Class AboutCommand có ID: org.o7planning.tutorial.rcp.cmd.about đã được tạo ở trước đây.

Chạy ứng dụng:

9.3- Toolbar

Đây là cấu trúc thanh công cụ nhìn thấy trên Eclipse IDE.

Tạo Coolbar:

Nhập vào
  • locationURI: toolbar:org.eclipse.ui.main.toolbar

locationURI: Là ID xác định vị trí mà Toolbar sẽ được đặt vào. toolbar:org.eclipse.ui.main.toolbar là một ID đã được khai báo sẵn của RCP Platform. Bạn cũng có thể tạo ra các locationURI để định nghĩa vị trí nào đó.

Nhập vào commandID:
  • org.eclipse.ui.file.exit
Đây là một ID được định nghĩa sẵn của RCP Platform, nó thực thi lệnh thoát ra khỏi ứng dụng workbench.
Tương tự tạo tiếp ToolItem (Kiểu Command) gọi đến Command:
  • org.o7planning.tutorial.rcp.cmd.about
Tương tự tạo tiếp Toolbar với id: toolbar0

9.4- View

Thêm "Extension Point"
  • org.eclipse.ui.views
Nhập vào:
  • id: org.o7planning.tutorial.rcp.view.contact
  • class: org.o7planning.tutorial.rcp.view.ContactView
Click vào link "class" để Eclipse tạo ra class trong trường hợp chưa có.
Class ContactView được tạo ra bạn có thể dễ dàng thiết kết nó với WindowBuilder. Nhấn phải vào class và mở với WindowBuilder.
Tương tự tạo các view khác.
CategoryView
  • name: Category
  • id: org.o7planning.tutorial.rcp.view.category
  • class: org.o7planning.tutorial.rcp.view.CategoryView
  • icon: icons/category16.png

HistoryView
  • name: History
  • id: org.o7planning.tutorial.rcp.view.history
  • class: org.o7planning.tutorial.rcp.view.HistoryView
  • icon: icons/history16.png

TaskView
  • name: Task
  • id: org.o7planning.tutorial.rcp.view.task
  • class: org.o7planning.tutorial.rcp.view.TaskView
  • icon: icons/task16.png

Đăng ký các View lên khung nhìn (Perspective)

Bản chất ở đây là chúng ta sẽ khai báo một khung nhìn với ID cụ thể nào đó có các View nào.
Thêm "Extension Point":
  • org.eclipse.ui.perspectiveExtensions
Chúng ta khai báo view : ContactView ở bên trái so với Editor.
Tiếp theo CategoryView chồng lên so với ContactView.
Tiếp theo HistoryView ở bên dưới so với ContactView
Cuối cùng TaskView được khai báo hiển thị trên khung nhìn có id là *, điều đó có nghĩa là nó sẽ hiển thị trên bất kỳ khung nhìn nào. Vị trí bên phải so với Editors.

Chạy lại ứng dụng:

Nếu Workbench không hiển thị các View, nhấn phải chuột vào "RCP Perspective" và chọn reset.

9.5- Perspective (Khung nhìn)

Một ứng dụng workbench có 1 hoặc nhiều khung nhìn.  Mỗi khung nhìn định nghĩa ra nó có thể chứa các View nào.

9.6- Editor

Nhấn vào Add để thêm Extension Point:
  • org.eclipse.ui.editors
Nhập vào các thông tin:
  • id: org.o7planning.tutorial.rcp.editor.user
  • name: UserEditor
  • icon: icons/user16.png
  • class: org.o7planning.tutorial.rcp.editor.UserEditor
Class UserEditor đã được tạo ra. Tiếp theo chúng ta tạo class UserEditorInput
  • UserEditorInput.java
package org.o7planning.tutorial.rcp.editor;

import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IPersistableElement;
 
public class UserEditorInput implements IEditorInput {
 
    @Override
    public Object getAdapter(Class adapter) {
        return null;
    }
 
    @Override
    public boolean exists() {
        return false;
    }
 
    @Override
    public ImageDescriptor getImageDescriptor() {
        return null;
    }
 
    @Override
    public String getName() {
        return "User Editor";
    }
 
    @Override
    public IPersistableElement getPersistable() {
        return null;
    }
 
    @Override
    public String getToolTipText() {
        return "User Editor";
    }
 
}
Và sửa class UserEditor
  • UserEditor.java
package org.o7planning.tutorial.rcp.editor;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.EditorPart;

public class UserEditor extends EditorPart {

  public static final String ID = "org.o7planning.tutorial.rcp.editor.user";

  public UserEditor() {

  }

  @Override
  public void doSave(IProgressMonitor monitor) {

  }

  @Override
  public void doSaveAs() {

  }

  /**
   * Important!!!
   */
  @Override
  public void init(IEditorSite site, IEditorInput input)
          throws PartInitException {
      if (!(input instanceof UserEditorInput)) {
          throw new PartInitException("Invalid Input: Must be "
                  + UserEditorInput.class.getName());
      }
      setSite(site);
      setInput(input);
  }

  @Override
  public boolean isDirty() {
      return false;
  }

  @Override
  public boolean isSaveAsAllowed() {
      return false;
  }

  @Override
  public void createPartControl(Composite parent) {
      // Add Code.
      // If you want to design with WindowBuilder Designer
      // Change code like:  (Important!!!)
      parent.setLayout(new FillLayout());
      Composite body = new Composite(parent, SWT.NONE);
  }

  @Override
  public void setFocus() {

  }

}
Bạn có thể mở UserEditor bằng WindowBuilder để thiết kế.

Tiếp theo chúng ta tạo một Command để gọi tới UserEditor.

Nhập vào:
  • id: org.o7planning.tutorial.rcp.cmd.user
  • name: Call UserEditor
  • defaultHandler: org.o7planning.tutorial.rcp.cmd.UserCommand
  • UserCommand.java
package org.o7planning.tutorial.rcp.cmd;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.handlers.HandlerUtil;
import org.o7planning.tutorial.rcp.editor.UserEditor;
import org.o7planning.tutorial.rcp.editor.UserEditorInput;
 
public class UserCommand extends AbstractHandler {
 
    public static final String ID = "org.o7planning.tutorial.rcp.cmd.user";
 
    @Override
    public Object execute(ExecutionEvent event) throws ExecutionException {
        IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event);
        IWorkbenchPage page = window.getActivePage();
 
        UserEditorInput input = new UserEditorInput();
        try {
            page.openEditor(input, UserEditor.ID);
        } catch (PartInitException e) {
            System.out.println("Error:" + this.getClass().getName() + ":" + e);
            e.printStackTrace();
            throw new ExecutionException("Error open UserEditor");
        }
        return null;
    }
 
}
Tiếp theo bạn tạo một MenuItem (Command) gọi trên Menu File:

Chạy lại ứng dụng:

10- Đóng gói và triển khai ứng dụng RCP

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

11- Tương tác View và Editor

Bạn có thể xem tiếp tài liệu: "Tương tác View và Editor":