程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 使用Eclipse RCP進行桌面程序開發(三):視圖和透視圖

使用Eclipse RCP進行桌面程序開發(三):視圖和透視圖

編輯:關於JAVA

Eclipse RCP開發中,和用戶進行交互最多的界面,應該是視圖了,而透視圖就是將已有 的視圖、菜單、工具欄、編輯器等等進行組合和布局。看完這一節,我們就可以建立如下圖 這樣的程序界面了。

首先我們來介紹一下視圖,建立一個視圖其實非常簡單,只要從 org.eclipse.ui.part.ViewPart繼承一個類,然後在plugin.xml中進行視圖的配置。其中, 向視圖中添加控件的操作,我們即可以手工編寫,也可以使用Designer插件,我這裡推薦大 家使用Designer插件,該插件對RCP提供功能非常強大的支持,如果使用Designer插件開發視 圖,則plugin.xml文件也不需要我們手動修改了。

比如我們上圖中的第一個視圖,就是從ViewPart繼承一個類,然後在上面加入了幾個swt 的控件,做得非常得簡單,而它的配置文件如下:

1<extension
2     point="org.eclipse.ui.views">
3   <view
4      class="cn.blogjava.youxia.views.FirstView"
5      id="cn.blogjava.youxia.views.FirstView"
6      name="第一個View"/>
7</extension>

可以看到,實現這個視圖的class為cn.blogjava.youxia.views.FirstView,那麼我們看 看FirstView.java吧:

1package cn.blogjava.youxia.views;
2
3import org.eclipse.jface.action.IMenuManager;
4import org.eclipse.jface.action.IToolBarManager;
5import org.eclipse.jface.viewers.TableViewer;
6import org.eclipse.swt.SWT;
7import org.eclipse.swt.widgets.Composite;
8import org.eclipse.swt.widgets.Label;
9import org.eclipse.swt.widgets.Table;
10import org.eclipse.swt.widgets.Text;
11import org.eclipse.ui.part.ViewPart;
12
13public class FirstView extends ViewPart {
14
15  private Table table;
16  private Text text_1;
17  private Text text;
18  public static final String ID = "cn.blogjava.youxia.views.FirstView"; // $NON-NLS-1$
19
20  /** *//**
21   * Create contents of the view part
22   * @param parent
23   */
24  @Override
25  public void createPartControl(Composite parent) {
26    Composite container = new Composite(parent, SWT.NONE);
27
28    final Label label = new Label(container, SWT.NONE);
29    label.setText("姓名:");
30    label.setBounds(56, 41, 36, 12);
31
32    text = new Text(container, SWT.BORDER);
33    text.setBounds(98, 38, 80, 15);
34
35    final Label label_1 = new Label(container, SWT.NONE);
36    label_1.setText("性別:");
37    label_1.setBounds(212, 41, 30, 12);
38
39    text_1 = new Text(container, SWT.BORDER);
40    text_1.setBounds(252, 38, 80, 15);
41
42    final TableViewer tableViewer = new TableViewer(container, SWT.BORDER);
43    //tableViewer.setInput(new Object());
44    table = tableViewer.getTable();
45    table.setBounds(56, 75, 374, 143);
46    table.setItemCount(10);
47    table.setLinesVisible(true);
48    //
49    createActions();
50    initializeToolBar();
51    initializeMenu();
52      }
53
54  /** *//**
55   * Create the actions
56   */
57  private void createActions() {
58    // Create the actions
59  }
60
61  /** *//**
62   * Initialize the toolbar
63   */
64  private void initializeToolBar() {
65    IToolBarManager toolbarManager = getViewSite().getActionBars()
66        .getToolBarManager();
67  }
68
69  /** *//**
70   * Initialize the menu
71   */
72  private void initializeMenu() {
73    IMenuManager menuManager = getViewSite().getActionBars()
74        .getMenuManager();
75  }
76
77  @Override
78  public void setFocus() {
79    // Set the focus
80  }
81
82  }

其中,添加控件的代碼由Disgner插件自動生成。這個時候,如果我們運行程序的話,我 們的視圖還不會被顯示出來。為了讓我們的視圖可以顯示,我們還需要修改 Perspective.java文件,代碼如下:

1package cn.blogjava.youxia.rcp_start;
2
3import org.eclipse.ui.IPageLayout;
4import org.eclipse.ui.IPerspectiveFactory;
5
6public class Perspective implements IPerspectiveFactory {
7
8  public void createInitialLayout(IPageLayout layout) {
9    String editorArea = layout.getEditorArea();
10    layout.addView("cn.blogjava.youxia.views.FirstView", IPageLayout.RIGHT, 0.2f, editorArea);
11  }
12}

運行程序,得到如下效果:

我們可以發現,上面這個視圖的標簽不是我們通常看到的波浪形,我們可以通過配置文件 的方式來更改產品的樣式。

首先,在plugin.xml中對org.eclipse.core.runtime.products擴展點的屬性進行更改, 如下:

<extension
2     id="product"
3     point="org.eclipse.core.runtime.products">
4   <product
5      application="cn.blogjava.youxia.rcp_start.application"
6      name="第一個RCP程序">
7     <property
8        name="preferenceCustomization"
9        value="plugin_customization.ini"/>
10   </product>
11</extension>

可見,我們為我們的產品添加了一個prefereneCustomization屬性,該屬性的值為 plugin_customization.ini文件,在該文件中,我們可以配置我們的樣式。在這裡,它的內 容如下:

1org.eclipse.ui/SHOW_TRADITIONAL_STYLE_TABS=false

2org.eclipse.ui/DOCK_PERSPECTIVE_BAR=topRight

事實上,在這個文件中可以定義的參數有上百個,大家可以查看Eclipse的文檔。

這個時候,效果應該是這樣的了:

好了,我們現在對以上的代碼做一個總結。我不是寫教科書,在Blog中也沒有寫得那麼詳 細的條件。我們這裡主要關注在哪個地方對代碼進行擴展,可以達到我們想要的效果。比如 ,我們要創建視圖,就是需要擴展org.eclipse.ui.part.ViewPart類,然後向其中添加控件 ,再然後配置plugin.xml文件,最後修改透視圖的代碼,以便它能夠顯示出來。

在ViewPart類中,我們添加控件的操作主要是在public void createPartControl (Composite parent)這個方法中進行,而方法最後會調用以下三個方法:

createActions();

initializeToolBar();

initializeMenu();

從這三個方法的方法名我們不難看出,它們的功能是創建視圖特有的菜單欄和工具欄的, 結合上一小節的內容,我們應該很快就可以探索到怎麼給視圖添加漂亮的工具欄了,這裡我 不再羅嗦。

再來看Perspective.java,不難發現,所有的透視圖類都需要實現IPerspectiveFactory 接口,而該接口的createInitialLayout方法,就是描述工作台窗口中編輯器和視圖的布局。 默認情況下,透視圖中只包含一個編輯器區域,就是我們第一節中看到的那個效果。在 createInitialLayou中,我們可以通過以下幾個方法向透視圖中添加視圖、編輯器和菜單:

addView  —— 添加視圖

addActionSet —— 添加菜單和工具欄

createFolder —— 創建一個IForderLayou,可以讓多個視圖重疊在同一個位置

寫到這裡,肯定有人會問,如果我要創建一個象Eclipse中的資源視圖這樣的視圖,該怎 麼做呢?這我們就要感謝org.eclipse.jface.viewers包了,Viewer,這裡翻譯為查看器,它 和視圖是不一樣的。JFace查看器是Jface對SWT部件的封裝,它簡化了我們對小部件的操作。 在使用查看器的時候,它的數據使用單獨的模型對象來保存,使用查看器的setInput方法可 以為查看器設置模型,此外,在使用查看器的時候,需要為它提供ContentProvider(內容提 供器)和LabelProvider(標簽提供器)。

JFace查看器主要分為以下幾類:

1. ListViewer: 對應於SWT的列表控件,目的是將列表中的元素映射至SWT列表控件

2. TreeViewer: 對應於SWT的樹控件,提供樹的展開和折疊等基本操作

3. TableViewer: 對應於SWT的表控件,映射表中的元素

4. TextViewer: 對應於SWT的StyledText控件,創建編輯器的時候,使用這個查看器是 最合適不過了。

好了,介紹性的文字就寫到這裡,我想大家一定已經知道了探索的方向。下面,我們看一 個簡單的示例,就是這篇文章開頭給出的效果圖。它是我模仿醫院管理系統做的一個簡單例 子,左邊的視圖就是使用了一個ListView查看器。這裡給出它的關鍵代碼:

public void createPartControl(Composite parent) {
2
3
4    viewer = new ListViewer(parent, SWT.BORDER);
5    viewer.setContentProvider(new PersonContentProvider());
6    viewer.setLabelProvider(new PersonLabelProvider());
7    viewer.setInput(new PersonModel());
8
9    createActions();
10    initializeToolBar();
11    initializeMenu();
12  }

可以看到,這裡需要設置內容提供器和標簽提供器和模型。下面,我們先創建一個病人類 Person.java:

1package cn.blogjava.youxia.views;
2
3public class Person {
4
5  private String name;
6  private String sex;
7  public String getName() {
8    return name;
9  }
10  public void setName(String name) {
11    this.name = name;
12  }
13  public String getSex() {
14    return sex;
15  }
16  public void setSex(String sex) {
17    this.sex = sex;
18  }
19
20}

下面,創建模型類PersonModel.java,在構造函數中我們向List中填入了幾個初始化數據 :

1package cn.blogjava.youxia.views;
2import java.util.ArrayList;
3
4public class PersonModel {
5
6  private ArrayList<Person> list = new ArrayList<Person>();
7
8  public interface Listener{
9    public void add(Person p);
10    public void remove(Person p);
11  }
12
13  private Listener listener;
14
15  public PersonModel(){
16    //向list裡面填入幾個初始化數據
17    Person p1 = new Person();
18    p1.setName("病人1");
19    p1.setSex("男");
20    list.add(p1);
21
22    Person p2 = new Person();
23    p2.setName("病人2");
24    p2.setSex("女");
25    list.add(p2);
26    
27  }
28
29  public void setListener(Listener listener){
30    this.listener = listener;
31  }
32
33  public void add(Person p){
34    list.add(p);
35    if(listener != null){
36      listener.add(p);
37    }
38  }
39
40  public void remove(Person p){
41    list.remove(p);
42    if(listener != null){
43      listener.remove(p);
44    }
45  }
46  
47  public ArrayList elements(){
48    return list;
49  }
50}

在這裡,我們還定義了一個Listener接口,為什麼要有這麼一個接口呢?就是為了讓我們 模型中的數據被改變時,查看器能夠相應更改。下面,我們實現內容提供器,該內容提供器 實現了PersonModel中定義的Listener接口,如下PersonContentProvider.java:

1package cn.blogjava.youxia.views;
2
3import org.eclipse.jface.viewers.IStructuredContentProvider;
4import org.eclipse.jface.viewers.Viewer;
5import org.eclipse.jface.viewers.ListViewer;
6
7import cn.blogjava.youxia.views.PersonModel.Listener;
8
9public class PersonContentProvider implements IStructuredContentProvider,
10    Listener {
11
12  PersonModel input;
13  ListViewer viewer;
14
15  public Object[] getElements(Object inputElement) {
16    // TODO 自動生成方法存根
17    return input.elements().toArray();
18  }
19
20  public void dispose() {
21    // TODO 自動生成方法存根
22    if(input != null){
23      input.setListener(null);
24    }
25    input = null;
26
27  }
28
29  public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
30    // TODO 自動生成方法存根
31    viewer = (ListViewer)viewer;
32    input = (PersonModel)newInput;
33    input.setListener(this);
34
35  }
36
37  public void add(Person p) {
38    // TODO 自動生成方法存根
39    viewer.add(p);
40  }
41
42  public void remove(Person p) {
43    // TODO 自動生成方法存根
44    viewer.remove(p);
45  }
46
47}

我們知道,列表中的元素都是Person類的對象,怎麼讓他們顯示出來呢,需要實現標簽提 供器,在標簽提供器中,我們可以設置對象顯示的圖標和文字,如下 PersonLabelProvider.java:

1package cn.blogjava.youxia.views;
2
3import org.eclipse.jface.viewers.ILabelProvider;
4import org.eclipse.jface.viewers.ILabelProviderListener;
5import org.eclipse.swt.graphics.Image;
6
7public class PersonLabelProvider implements ILabelProvider {
8
9  public Image getImage(Object element) {
10    return null;
11  }
12
13  public String getText(Object element) {
14    // TODO 自動生成方法存根
15    return ((Person)element).getName();
16  }
17
18  public void addListener(ILabelProviderListener listener) {
19    // TODO 自動生成方法存根
20
21  }
22
23  public void dispose() {
24    // TODO 自動生成方法存根
25
26  }
27
28  public boolean isLabelProperty(Object element, String property) {
29    // TODO 自動生成方法存根
30    return false;
31  }
32
33  public void removeListener(ILabelProviderListener listener) {
34    // TODO 自動生成方法存根
35
36  }
37
38}

運行程序,就得到了文章開頭的效果,但是不能在右邊的視圖中顯示病人的詳細信息。

如果要做到視圖的交互,需要添加事件的監聽器。使用Java 進行GUI開發的人應該都不會 陌生,而我在RCP上,也處於探索階段,更深一步的內容,讓我們自己慢慢研究吧。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved