From:http://www.eclipseworld.org/bbs/read.php?tid=1296
Master/Details是UI设计中常见的一种模式。他有一组(列表或成树状结构)的master和一个被选中 master驱动的details集组成。
master是一些不同的对象,通过对master的选择,驱动details的UI发生变化。在下面的图中,有3各不同的master,分别对应3种不同的UI:
描述:1 初始状态:只有master的树状列表
图片:
描述:2 选中一个master,是一个对象
图片:
描述:3 选中另外一个master,是一个不同的对象
图片:
描述:4 选中另外一个master,又是一个不同的对象
图片:
首先我们需要一个FormEditor,在这个FormEditor中添加我们要显示的页
最后我们只要实现不同的page就可以了。
- public class AdvancedFormEditor extends FormEditor{
- public AdvancedFormEditor(){
- super ();
- }
- protected void addPages(){
- try {
- addPage( new MainPage( this ));
- } catch (PartInitException e){
- e.printStackTrace();
- }
- }
- public void doSave(IProgressMonitor monitor){
- }
- public void doSaveAs(){
- }
- public boolean isSaveAsAllowed(){
- return false ;
- }
- }
然后来构造这个页,ScrolledPropertiesBlock对象就是我们存放master的地方。
在这个ScrolledPropertiesBlock中,我们将masters以树状结构显示出来。
- public class MainPage extends FormPage{
- private ScrolledPropertiesBlock block;
- public MainPage(FormEditor editor){
- super (editor, "main" , "Advanced Form Editor" );
- block= new ScrolledPropertiesBlock();
- }
- /* ManagedForm封装了form元素的生命周期管理与各个form元素之间的事件通知
- * ManagedForm本身并不是一个form,他包含了一个form并且可以注册IFormPart。
- * 可以将ManagedForm看作是'viewers',form和managed form之间的关系就好像
- * Table与TableViewer的关系一样。
- */
- protected void createFormContent(IManagedForm managedForm){
- ScrolledForm form=managedForm.getForm();
- form.setText( "Advanced Form Editor" );
- form.setBackgroundImage(Images.getImage( "icons/form_banner.gif" ));
- //尽量在最后调用这个方法
- block.createContent(managedForm);
- }
- }
主要的内容还是在ScrolledPropertiesBlock这个类中。
Eclipse Forms对Master/Details 模式体供了一个实现。具备以下属性:
1、当details part被创建的时候, master part的工厂方法createMasterPart还是抽象的,必须先被其子类实现。
2、Master and details实际上是sash form的两个子元素。可以通过调整sash的大小来改变他们俩的区域。
3、由于sash form的特性, master 与 details parts可以被横向或纵向排列。
master/details 块的目的就是创建一个tree或table section,通过managed form来唤醒selection事件。
如果details part可以处理被选中的master对象,他就会切换不同的页来显示属性。
当子类在创建顶级master/details时应该注意:
1、创建一个用来驱动details的master part
2、为form tool bar提供actions,一般显示在form的右上方,与form标题区同排
3、注册detail页,master part可以条用注册的所有detail
- public class ScrolledPropertiesBlock extends MasterDetailsBlock {
- class MasterContentProvider...{
- ... ...
- }
- class MasterLabelProvider...{
- ... ...
- }
- protected void createMasterPart( final IManagedForm managedForm,Composite parent) {
- FormToolkit toolkit = managedForm.getToolkit();
- Section section = toolkit.createSection(parent, Section.DESCRIPTION|Section.TITLE_BAR);
- section.setText( "模型列表" );
- section.setDescription( "以下把两种模型列在表中,可以通过选择不同的模型在右边切换编辑页面进行编辑" );
- section.marginWidth = 10 ;
- section.marginHeight = 5 ;
- toolkit.createCompositeSeparator(section);
- Composite client = toolkit.createComposite(section, SWT.WRAP);
- GridLayout layout = new GridLayout();
- layout.numColumns = 2 ;
- client.setLayout(layout);
- Table t = toolkit.createTable(client, SWT.NULL);
- t.setLayoutData( new GridData(GridData.FILL_BOTH));
- /*
- * 为当前parent内,toolkit所创建的widget添加边框。如果widget已经设置了SWT.BORDER,
- * 则不会再为其添加边框。
- */
- toolkit.paintBordersFor(client);
- Button b = toolkit.createButton(client, "添加" , SWT.PUSH);
- b.setLayoutData( new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
- /* IFormPart管理了整个Part的dirty state, saving, commit, focus, selection changes等等这样的事件。
- * 并不是form中的每一个control都需要成为一个form part,最好将一组control通过实现IFormPart变成一个Part.
- * 一般来说Section就是一个自然形成的组,所以Eclipse Form提供了一个SectionPart的实现,它包含一个Section
- * 的实例。
- */
- final SectionPart spart = new SectionPart(section);
- managedForm.addPart(spart);
- TableViewer viewer = new TableViewer(t);
- viewer.addSelectionChangedListener( new ISelectionChangedListener() {
- public void selectionChanged(SelectionChangedEvent event) {
- managedForm.fireSelectionChanged(spart, event.getSelection());
- }
- });
- viewer.setContentProvider( new MasterContentProvider());
- viewer.setLabelProvider( new MasterLabelProvider());
- viewer.setInput( new SimpleFormEditorInput( "simple " ));
- /**
- * Sets the client of this expandable composite. The client must not be
- * null and must be a direct child of this container.
- */
- section.setClient(client);
- }
- protected void createToolBarActions(IManagedForm managedForm) {
- final ScrolledForm form = managedForm.getForm();
- Action haction = new Action( "hor" , Action.AS_RADIO_BUTTON) {
- public void run() {
- sashForm.setOrientation(SWT.HORIZONTAL);
- form.reflow( true );
- }
- };
- haction.setChecked( true );
- haction.setToolTipText( "横向排列" );
- haction.setImageDescriptor(Images.getImageDescriptor( "icons/th_horizontal.gif" ));
- Action vaction = new Action( "ver" , Action.AS_RADIO_BUTTON) {
- public void run() {
- sashForm.setOrientation(SWT.VERTICAL);
- form.reflow( true );
- }
- };
- vaction.setChecked( false );
- vaction.setToolTipText( "纵向排列" );
- vaction.setImageDescriptor(Images.getImageDescriptor( "icons/th_vertical.gif" ));
- form.getToolBarManager().add(haction);
- form.getToolBarManager().add(vaction);
- }
- protected void registerPages(DetailsPart detailsPart){
- detailsPart.registerPage(TopicDatadefSet. class , new DatadefSetDetailsPage());
- detailsPart.registerPage(TopicCategory. class , new TopicCatalogDetailsPage());
- detailsPart.registerPage(TopicDef. class , new TopicDetailsPage());
- }
- }
大家应该注意到上面的程序中有两个很重要的方法:
- TableViewer viewer = new TableViewer(t);
- viewer.addSelectionChangedListener( new ISelectionChangedListener() {
- public void selectionChanged(SelectionChangedEvent event) {
- managedForm.fireSelectionChanged(spart, event.getSelection());
- }
- });
这里面的event.getSelection()得到的就是这个master的对象,也就是下面这个方法中的
TopicDatadefSet、TopicCategory、TopicDef3个对象。而下面这个方法就是把每个master对象与其detail页关联起来:
- protected void registerPages(DetailsPart detailsPart){
- detailsPart.registerPage(TopicDatadefSet. class , new DatadefSetDetailsPage());
- detailsPart.registerPage(TopicCategory. class , new TopicCatalogDetailsPage());
- detailsPart.registerPage(TopicDef. class , new TopicDetailsPage());
- }
- public class DatadefSetDetailsPage implements IDetailsPage{
- ... ...
- }