RCP扩展Editor,及如何不重复打开相同内容的page

转自 http://hi.baidu.com/if1i/blog/item/500c26f4eadffdd7f2d38546.html

eclipse 3.6 RCP 教程 -4- view 和 editor 介绍以及用 command 调用 editor

下面介绍 view 和 editor 的基础知识,以及如何通过 command 来与 editor 通信,详见:
http://www.vogella.de/articles/EclipseEditors/article.html 不过 tutorial 有点问题,
解决问题要参考它的工程源码:http://www.vogella.de/code/codeeclipse.html
(1)以 "rcp application with a view" 模板来创建一个新的 RCP 工程 "de.ytao.rcp.editor.example",创建如下三个类:
package de.ytao.rcp.editor.example.model;
public class Person {
 private String firstName;
 private String lastName;
 private Address address;
 public Person(String firstName, String lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
 }
 public String getFirstName() {
  return firstName;
 }
 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }
 public String getLastName() {
  return lastName;
 }
 public void setLastName(String lastName) {
  this.lastName = lastName;
 }
 public Address getAddress() {
  return address;
 }
 public void setAddress(Address address) {
  this.address = address;
 }
 @Override
 public String toString() {
  return firstName + " " + lastName;
 }
 @Override
 public int hashCode() { // 重写 hashCode() 和 equals() 方法后,两对象只要 firstName 和 lastName 相等,即认为两对象相等
  final int prime = 31;
  int result = 1;
  result = prime * result
    + ((firstName == null) ? 0 : firstName.hashCode());
  result = prime * result
    + ((lastName == null) ? 0 : lastName.hashCode());
  return result;
 }
 @Override
 public boolean equals(Object obj) {
  if (this == obj)
   return true;
  if (obj == null)
   return false;
  if (getClass() != obj.getClass())
   return false;
  Person other = (Person) obj;
  if (firstName == null) {
   if (other.firstName != null)
    return false;
  } else if (!firstName.equals(other.firstName))
   return false;
  if (lastName == null) {
   if (other.lastName != null)
    return false;
  } else if (!lastName.equals(other.lastName))
   return false;
  return true;
 }
}
 
 
package de.ytao.rcp.editor.example.model;
public class Address {
 private String street;
 private String number;
 private String postalCode;
 private String city;
 private String country;
 public String getStreet() {
  return street;
 }
 public void setStreet(String street) {
  this.street = street;
 }
 public String getNumber() {
  return number;
 }
 public void setNumber(String number) {
  this.number = number;
 }
 public String getPostalCode() {
  return postalCode;
 }
 public void setPostalCode(String postalCode) {
  this.postalCode = postalCode;
 }
 public String getCity() {
  return city;
 }
 public void setCity(String city) {
  this.city = city;
 }
 public String getCountry() {
  return country;
 }
 public void setCountry(String country) {
  this.country = country;
 }
 public String toString() {
  return street + " " + number + " " + postalCode + " " + city + " "
    + country;
 }
}
 
 
package de.ytao.rcp.editor.example.model;
import java.util.ArrayList;
import java.util.List;
public class MyModel {
 private List<Person> persons = new ArrayList<Person>();
 public List<Person> getPersons() {
  return persons;
 }
 public MyModel() {
  // Just for testing we hard-code the persons here:
  Person person = new Person("Lars", "Vogel");
  person.setAddress(new Address());
  person.getAddress().setCountry("Germany");
  persons.add(person);
  person = new Person("Jim", "Knopf");
  person.setAddress(new Address());
  person.getAddress().setCountry("Germany");
  persons.add(person);
 }
}

(2)修改 view.java,主要 tableviewer 变更为 listviewer,并且当用户数据填入,注意以下成员变量和方法:
private ListViewer viewer; public void createPartControl(Composite parent) {
        viewer = new ListViewer(parent);
        viewer.setContentProvider(ArrayContentProvider.getInstance());
        viewer.setLabelProvider(new LabelProvider() {
                @Override
                public String getText(Object element) {
                        Person p = (Person) element;
                        return p.getFirstName() + " " + p.getLastName();
                };
        });
        viewer.setInput(new MyModel().getPersons());
// 使 view 生效,这样 veiw 通过 command 打开相应的 editor。workbench 有一个 site 并用于与其它 workbench 通信。

        getSite().setSelectionProvider(viewer); }
public void setFocus() {
        viewer.getControl().setFocus();
}
 
(3)使 editor 可见,注释掉 Perspective.java 中的一行
// layout.setEditorAreaVisible(false);
(4)新建一个 EditorInput,它赋于 editor 内容,这样 Editor 才能打开显示
package: de.ytao.rcp.intro.editor.editors;
Name: MyPersonEditorInput
super class: org.eclipse.ui.IEditorInput
在类中增加如下内容:
private final Person person; 
public MyPersonEditorInput(Person person){
 this.person = person;
}
public Person getPerson() {
 return person;
}
修改 getName() 方法:return person.toString();
修改 getToolTipText() 方法 return person.getFirstName(); 这两个方法都不能返回 null 值
建议增加下面两个过程,它们能决定 editor 是否已经打开
 @Override  
 public boolean equals(Object obj) {  
     if (super.equals(obj)) {  
  return true;  
     }  
     if (obj instanceof MyPersonEditorInput) {  
  return person.equals(((MyPersonEditorInput) obj).getPerson());  
     }  
     return false;  
 } 
 @Override  
 public int hashCode() {  
     return person.hashCode();  
 } 
(5)增加 editor 类,注意这种方式与 windowbuidler 方式的不同。windowbuilder 是能直接新建 EditorPart 类型类,
而这种手动方式是先增加扩展点,然后以 EditorPart 作为超类。并能继承 abstarct 方法,也是一种间接依据模板生成代码的方式。
Package: de.ytao.rcp.intro.editor.editors
Name: MyPersonEditor
Superclass: org.eclipse.ui.part.EditorPart
package de.ytao.rcp.intro.editor.editors;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.EditorPart;
import de.ytao.rcp.editor.example.model.Person;
public class MyPersonEditor extends EditorPart {
 public static final String ID = "de.ytao.rcp.intro.editor.editors.MyPersonEditor";
 private Person person;
 private Text text2;
 public MyPersonEditor() {
 }
 @Override
 public void doSave(IProgressMonitor monitor) {
  // TODO Auto-generated method stub
 }
 @Override
 public void doSaveAs() {
  // TODO Auto-generated method stub
 }
 @Override
 public void init(IEditorSite site, IEditorInput input)
   throws PartInitException {
  setSite(site);
  setInput(input);
  person = ((MyPersonEditorInput) input).getPerson();
  setPartName(person.getFirstName());
 }
 @Override
 public boolean isDirty() {
  if (person.getAddress().getCountry().equals(text2.getText())) {
   return false;
  }
  return true;
 }
 @Override
 public boolean isSaveAsAllowed() {
  // TODO Auto-generated method stub
  return false;
  
 }
 @Override
 public void createPartControl(Composite parent) {
  GridLayout layout = new GridLayout();
  layout.numColumns = 2;
  parent.setLayout(layout);
  Label label1 = new Label(parent, SWT.BORDER);
  label1.setText("Person: ");
  Label personName = new Label(parent, SWT.BORDER);
  personName.setText(person.toString());
  Label label2 = new Label(parent, SWT.BORDER);
  label2.setText("Country");
  text2 = new Text(parent, SWT.BORDER);
  text2.setText(person.getAddress().getCountry());
 }
 @Override
 public void setFocus() {
  // TODO Auto-generated method stub
 }
}
(6)经过以上步骤,还差一个 veiw 来触发 editor 的实现,通道已经建立了,触发有两种方法,加事件或通过 command 调用 editor,下面介绍第二种方法
-> command 建立
新建一个 command :
id: de.vogella.rcp.intro.editor.handler.CallEditor
name: CallEditor
defaultHandler: de.vogella.rcp.intro.editor.handler.CallEditor
然后新建一个 command 命令对应的类:
package: de.vogella.rcp.intro.editor.handler
name: CallEditor
superclass: org.eclipse.core.commands.AbstractHandler
补充完整 CallEditor:
public Object execute(ExecutionEvent event) throws ExecutionException {
 // Get the view
 IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event);
 IWorkbenchPage page = window.getActivePage();
 View view = (View) page.findView(View.ID); // 这个 view 是用户自定义的 view.java,就是显示在 RCP 左边
 // Get the selection
 ISelection selection = view.getSite().getSelectionProvider()
   .getSelection();
 if (selection != null && selection instanceof IStructuredSelection) {
  Object obj = ((IStructuredSelection) selection).getFirstElement();
  // If we had a selection lets open the editor
  if (obj != null) {
   Person person = (Person) obj;
   MyPersonEditorInput input = new MyPersonEditorInput(person); // 构造通道 
   try {
    page.openEditor(input, MyPersonEditor.ID); // 将通道跟 editor 绑在一起
   } catch (PartInitException e) {
    System.out.println(e.getStackTrace());
   }
  }
 }
 return null;
}
-> 调用 command
补充(2)提到的 createPartControl 方法,增加 hookDoubleClickCommand(); 调用,然后创建 hookDoubleClickCommand 方法:
private void hookDoubleClickCommand() {
 viewer.addDoubleClickListener(new IDoubleClickListener() {
  public void doubleClick(DoubleClickEvent event) {
   IHandlerService handlerService = (IHandlerService) getSite()
     .getService(IHandlerService.class);
   try {
    handlerService.executeCommand(
      "de.ytao.rcp.intro.editor.handler.CallEditor", null);
   } catch (Exception ex) {
    throw new RuntimeException(
      "de.ytao.rcp.intro.editor.handler.CallEditor not found");
   }
  }
 });
}
(7)收尾
运行 application,就能看到左边一个 list,里面有 item,点击右边就能打开一个 editor,显示相应的 person 信息,
反复点击不会重复打开 editor,但界面显示上可以改善一下,比如,窗口可以打开即最大化,
修改 ApplicationWorkbenchWindowAdvisor 类中的 postWindowOpen():
public void postWindowOpen() 
{ 
  this.getWindowConfigurer().getWindow().getShell().setMaximized(true); 
}
(8)附——针对(6)中的提到的另一种方法,可以这样实现:
删除掉  commands 扩展和 command,以及调用 command 的类,并修改 View.java 中方法:
private void hookDoubleClickCommand() {
 viewer.addDoubleClickListener(new IDoubleClickListener() {
  public void doubleClick(DoubleClickEvent event) {
   try  
     { 
    ISelection selection = getSite().getSelectionProvider().getSelection();
    if (selection != null && selection instanceof IStructuredSelection) {
     Object obj = ((IStructuredSelection) selection).getFirstElement();
     // If we had a selection lets open the editor
     if (obj != null) {
      Person person = (Person) obj;
      getViewSite().getWorkbenchWindow().getActivePage().openEditor(new MyPersonEditorInput(person), MyPersonEditor.ID);
     }
    }
      
     }  
      catch (Exception ex)  
     { 
      System.out.println(ex); 
     }
  }
 });
}
也是同样的效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值