Question

I've got some trouble using JFace MasterDetailsPart for the first time. The details page is not shown - and when I select a new Item, the event is not fired. I couldn't find any good example or tutorial for this, even the JavaDoc could not help me.

The detailspart just implements IDetailsPart and SYSOUT's a message when it is initialized (which is shown), but the Label is not shown: Here is the DetailsPart-Code:

public class Einzelansicht implements IDetailsPage{

    public Einzelansicht() {
        // TODO Auto-generated constructor stub

    }


    @Override
    public void commit(boolean arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void dispose() {
        // TODO Auto-generated method stub

    }

    @Override
    public void initialize(IManagedForm arg0) {
        System.out.println("initialize");



    }

    @Override
    public boolean isDirty() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean isStale() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public void refresh() {
        // TODO Auto-generated method stub

    }

    @Override
    public void setFocus() {
        // TODO Auto-generated method stub

    }

    @Override
    public boolean setFormInput(Object arg0) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public void selectionChanged(IFormPart arg0, ISelection arg1) {
System.out.println("!!");

    }

    @Override
    public void createContents(Composite arg0) {
        arg0.setLayout(new GridLayout());
        Label label = new Label(arg0, 0);
        label.setText("Einzel");

    }

}

Pretty straight forward, I guess, nothing special here which should fail. Now my MasterDetaislBlock:

public class BlockZwei extends MasterDetailsBlock {

    private FormToolkit toolkit;
    private IManagedForm form;

    /**
     * Create the master details block.
     */
    public BlockZwei() {
        // Create the master details block
    }

    /**
     * Create contents of the master details block.
     * 
     * @param managedForm
     * @param parent
     */
    @Override
    protected void createMasterPart(final IManagedForm managedForm,
            Composite parent) {
        toolkit = managedForm.getToolkit();
        //
        form = managedForm;

        final TableViewer tableViewer = new TableViewer(parent);
        ArrayContentProvider arrayContent = ArrayContentProvider.getInstance();
        tableViewer.setContentProvider(arrayContent);
        String[] strings = new String[] { "Eins", "Zwei" };
        tableViewer.setInput(strings);
        tableViewer
                .addSelectionChangedListener(new ISelectionChangedListener() {

                    @Override
                    public void selectionChanged(SelectionChangedEvent arg0) {
                        managedForm.fireSelectionChanged(detailsPart, arg0.getSelection());



                    }
                });
    }
    /**
     * Register the pages.
     * 
     * @param part
     */
    @Override
    protected void registerPages(DetailsPart part) {
        part.registerPage(Einzelansicht.class, new Einzelansicht());


    }

As you can see, I register a listener to the selection, and as far as I understand the event should trigger a event on the detailspage. Last but not least, my ViewPart with the MDB

public class View extends ViewPart {
    public static final String ID = "EclipseRCPStinkt.view";


    /**
     * This is a callback that will allow us to create the viewer and initialize
     * it.
     */
    public void createPartControl(Composite parent) {
        ManagedForm managed = new ManagedForm(parent);
        BlockZwei block = new BlockZwei();
        block.createContent(managed);
        managed.refresh();
    }

    /**
     * Passing the focus request to the viewer's control.
     */
    public void setFocus() {

    }
}

Did I forget to call something? I really could not find my mistake

Was it helpful?

Solution

I had the same problem and there is not much online resources about how to implement MasterDetails pattern in eclipse. I came here, but unfortunately nobody has answered yet, so I had to investigate it on my own. I mainly tried to analyse the ExtensionsPage class of eclipse editor of plugin.xml file. I am quite fresh to Eclipse and Java in general, so do not take my answer as an oracle, but since there are no other answers, it may have some use for you.

Using debugger you will notice that the method initialize() is called when you register a page, so it does not depend on your current selection.

My MasterDetailsBloc class is something like this:

public class MyMasterDetailsBlock extends MasterDetailsBlock{

    private SectionPart fMasterSectionPart;
    private Section fMasterSection;
    private TreeViewer fTreeViewer;

    [...]

     /**
     * Create contents of the master details block.
     * @param managedForm
     * @param parent
     */
    @Override
    protected void createMasterPart(IManagedForm managedForm, Composite parent) {
        fMasterSection = managedForm.getToolkit().createSection(parent,
                   ExpandableComposite.EXPANDED | ExpandableComposite.TITLE_BAR);
        fMasterSectionPart = new SectionPart(fMasterSection, 0);

        Composite composite = new Composite(fMasterSection, SWT.RIGHT);
        fTreeViewer = new TreeViewer(composite, SWT.FILL);
        fTreeViewer.setContentProvider(new MyContentProvider());
        fTreeViewer.setLabelProvider(new MyLabelProvider());
        fTreeViewer.setInput(fMyInput);

        fTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
            @Override
            public void selectionChanged(SelectionChangedEvent event) {
                detailsPart.selectionChanged(fMasterSectionPart,
                                             event.getSelection());
           }
       );

       [...]
}

     /**
     * Register the pages.
     * @param part
     */
    @Override
    protected void registerPages(DetailsPart part) {
        part.registerPage(MyClass.class, new MyClassDetailsPage());
    }
    [...]
}

The trick seems to be that you need to create a SectionPart that wraps your master Section widget (in my code these are fMasterSectionPart and fMasterSection respectively, initialized in the function createMasterPart()). Then you need to add a ISelectionChangedListener object to your viewer, where you call detailsPart.selectionChanged() and voila. Registering pages goes intuitively, but I noticed that you have to register each class separately, i.e. registering base class will not work for derived classes. This is however just first observation and I haven't investigated the mechanism deeply yet.

It may happen that this is ugly and dirty solution and "you just shouldn't do it this way". Nevertheless this is the only way I could make it work, and there is no material on web about how to do it right. I hope I could help.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top