Search code examples
javaeclipse-pluginswtjfacemaster-detail

How to implement a simple master-detail in a JFace WizardPage


I want to implement a simple master-detail scenario in Jface WizardPage: The WizardPage will have one table with some names, upon selecting a row in the table the bottom part of the WizardPage containing texts/labels gets updated with the details corresponding to the selection in the table.

I searched internet and found only examples that run as SWT application: http://dev.eclipse.org/viewcvs/viewvc.cgi/org.eclipse.jface.examples.databinding/src/org/eclipse/jface/examples/databinding/snippets/Snippet010MasterDetail.java?view=markup

1   /*******************************************************************************
2    * Copyright (c) 2007, 2009 Brad Reynolds and others.
3    * All rights reserved. This program and the accompanying materials
4    * are made available under the terms of the Eclipse Public License v1.0
5    * which accompanies this distribution, and is available at
6    * http://www.eclipse.org/legal/epl-v10.html
7    *
8    * Contributors:
9    *     Brad Reynolds - initial API and implementation
10   *     Matthew Hall - bug 260329
11   ******************************************************************************/
12  
13  package org.eclipse.jface.examples.databinding.snippets;
14  
15  import java.beans.PropertyChangeListener;
16  import java.beans.PropertyChangeSupport;
17  
18  import org.eclipse.core.databinding.DataBindingContext;
19  import org.eclipse.core.databinding.UpdateValueStrategy;
20  import org.eclipse.core.databinding.beans.BeansObservables;
21  import org.eclipse.core.databinding.observable.Realm;
22  import org.eclipse.core.databinding.observable.value.IObservableValue;
23  import org.eclipse.jface.databinding.swt.SWTObservables;
24  import org.eclipse.jface.databinding.viewers.ViewersObservables;
25  import org.eclipse.jface.viewers.ArrayContentProvider;
26  import org.eclipse.jface.viewers.ListViewer;
27  import org.eclipse.swt.SWT;
28  import org.eclipse.swt.layout.GridLayout;
29  import org.eclipse.swt.widgets.Display;
30  import org.eclipse.swt.widgets.Shell;
31  import org.eclipse.swt.widgets.Text;
32  
33  /**
34   * Snippet that displays a simple master detail use case. A list of persons is
35   * displayed in a list and upon selection the name of the selected person will
36   * be displayed in a Text widget.
37   */
38  public class Snippet010MasterDetail {
39          public static void main(String[] args) {
40                  final Display display = new Display();
41                  Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() {
42                          public void run() {
43                                  Shell shell = new Shell(display);
44                                  shell.setLayout(new GridLayout());
45  
46                                  Person[] persons = new Person[] { new Person("Me"),
47                                                  new Person("Myself"), new Person("I") };
48  
49                                  ListViewer viewer = new ListViewer(shell);
50                                  viewer.setContentProvider(new ArrayContentProvider());
51                                  viewer.setInput(persons);
52  
53                                  Text name = new Text(shell, SWT.BORDER | SWT.READ_ONLY);
54  
55                                  // 1. Observe changes in selection.
56                                  IObservableValue selection = ViewersObservables
57                                                  .observeSingleSelection(viewer);
58  
59                                  // 2. Observe the name property of the current selection.
60                                  IObservableValue detailObservable = BeansObservables
61                                                  .observeDetailValue(selection, "name", String.class);
62  
63                                  // 3. Bind the Text widget to the name detail (selection's
64                                  // name).
65                                  new DataBindingContext().bindValue(SWTObservables.observeText(
66                                                  name, SWT.None), detailObservable,
67                                                  new UpdateValueStrategy(false,
68                                                                  UpdateValueStrategy.POLICY_NEVER), null);
69  
70                                  shell.open();
71                                  while (!shell.isDisposed()) {
72                                          if (!display.readAndDispatch())
73                                                  display.sleep();
74                                  }
75                          }
76                  });
77                  display.dispose();
78          }
79  
80          public static class Person {
81                  private String name;
82                  private PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);
83  
84                  Person(String name) {
85                          this.name = name;
86                  }
87  
88                  public void addPropertyChangeListener(PropertyChangeListener listener) {
89                          changeSupport.addPropertyChangeListener(listener);
90                  }
91                  
92                  public void removePropertyChangeListener(PropertyChangeListener listener) {
93                          changeSupport.removePropertyChangeListener(listener);
94                  }
95                  
96                  /**
97                   * @return Returns the name.
98                   */
99                  public String getName() {
100                         return name;
101                 }
102 
103                 public String toString() {
104                         return name;
105                 }
106         }
107 }

How to integrate this in a JFace Wizard? And this wizard should run as a Eclipse plugin


Solution

  • Here is a working example:

    public static void main(String[] args) {
        final Display display = new Display();
        final Shell shell = new Shell(display);
    
        WizardDialog wizardDialog = new WizardDialog(shell, new MyWizard());
        wizardDialog.open();
    
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
        display.dispose();
    }
    
    private static class MyWizard extends Wizard
    {
        protected MyWizardPage one;
    
        public MyWizard()
        {
            super();
        }
    
        @Override
        public void addPages() {
            one = new MyWizardPage("Page One");
            addPage(one);
        }
    
        @Override
        public boolean performFinish() {
            return false;
        }
    
    }
    
    private static class MyWizardPage extends WizardPage
    {
        protected MyWizardPage(String pageName) {
            super(pageName);
        }
    
        @Override
        public void createControl(Composite comp)
        {
            Composite container = new Composite(comp, SWT.NULL);
            GridLayout layout = new GridLayout(2, true);
            container.setLayout(layout);
    
            final TableViewer viewer = new TableViewer(container, SWT.READ_ONLY);
    
            // First column is for the name
            TableViewerColumn col = createTableViewerColumn("Name", 100, 0, viewer);
            col.setLabelProvider(new ColumnLabelProvider() {
                @Override
                public String getText(Object element) {
                    if(element instanceof Person)
                    {
                        return ((Person)element).getName();
                    }
                    return "";
                }
            });
    
            // First column is for the location
            TableViewerColumn col2 = createTableViewerColumn("Location", 100, 1, viewer);
            col2.setLabelProvider(new ColumnLabelProvider() {
                @Override
                public String getText(Object element) {
                    if(element instanceof Person)
                    {
                        return ((Person)element).getLocation();
                    }
                    return "";
                }
            });
    
            final Table table = viewer.getTable();
            table.setHeaderVisible(true);
            table.setLinesVisible(true);
            GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
            data.horizontalSpan = 2;
            table.setLayoutData(data);
    
            /* Add listener to listen for selection change */
            final Text name = new Text(container, SWT.BORDER);
            name.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
            final Text location = new Text(container, SWT.BORDER);
            location.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
    
            viewer.addSelectionChangedListener(new ISelectionChangedListener() {
    
                @Override
                public void selectionChanged(SelectionChangedEvent arg0) {
                    IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
                    Person person = (Person) selection.getFirstElement();
    
                    name.setText(person.getName());
                    location.setText(person.getLocation());
                }
            });
    
            viewer.setContentProvider(ArrayContentProvider.getInstance());
    
            final Person[] persons = new Person[] { new Person("Baz", "Loc"),
                    new Person("BazBaz", "LocLoc"), new Person("BazBazBaz", "LocLocLoc") };
    
            viewer.setInput(persons);
    
            setControl(container);
            setPageComplete(false);
        }
    }
    
    private static TableViewerColumn createTableViewerColumn(String title, int bound, final int colNumber, TableViewer viewer) {
        final TableViewerColumn viewerColumn = new TableViewerColumn(viewer, SWT.NONE);
        final TableColumn column = viewerColumn.getColumn();
        column.setText(title);
        column.setWidth(bound);
        column.setResizable(true);
        column.setMoveable(false);
    
        return viewerColumn;
    }
    
    public static class Person {
        private String name;
        private String location;
    
        public Person(String name, String location) {
            this.name = name;
            this.location = location;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getLocation() {
            return location;
        }
    
        public void setLocation(String location) {
            this.location = location;
        }
    
        public String toString()
        {
            return name + " " + location;
        }
    }
    

    And here is a screenshot:

    enter image description here

    As you can see, the text fields are filled with the content of the table. I'm sure you are able to use this code snippet for your purpose.