org.eclipse.net4j.util.ui.views.MasterDetailsView.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.net4j.util.ui.views.MasterDetailsView.java

Source

/*
 * Copyright (c) 2008, 2009, 2011, 2012, 2015 Eike Stepper (Berlin, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 */
package org.eclipse.net4j.util.ui.views;

import org.eclipse.net4j.util.ObjectUtil;
import org.eclipse.net4j.util.internal.ui.bundle.OM;
import org.eclipse.net4j.util.internal.ui.messages.Messages;
import org.eclipse.net4j.util.ui.UIUtil;
import org.eclipse.net4j.util.ui.actions.SafeAction;
import org.eclipse.net4j.util.ui.actions.SashLayoutAction;
import org.eclipse.net4j.util.ui.widgets.CoolBarComposite;
import org.eclipse.net4j.util.ui.widgets.SashComposite;

import org.eclipse.jface.action.IContributionManager;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;

/**
 * @author Eike Stepper
 * @since 2.0
 */
public abstract class MasterDetailsView extends MultiViewersView {
    private StructuredViewer master;

    private CTabFolder detailsFolder;

    private Object currentMasterElement = new Object();

    private String[] detailTitles;

    private CTabItem[] detailItems;

    private StructuredViewer[] details;

    private int currentDetailIndex;

    private SashComposite sash;

    public MasterDetailsView() {
    }

    public StructuredViewer getMaster() {
        return master;
    }

    public StructuredViewer[] getDetails() {
        return details;
    }

    public String[] getDetailTitles() {
        return detailTitles;
    }

    public Object getCurrentMasterElement() {
        return currentMasterElement;
    }

    public int getCurrentDetailIndex() {
        return currentDetailIndex;
    }

    public String getCurrentDetailTitle() {
        if (detailTitles == null || currentDetailIndex == -1) {
            return null;
        }

        return detailTitles[currentDetailIndex];
    }

    @Override
    protected Control createUI(Composite parent) {
        sash = new SashComposite(parent, SWT.NONE, 10, 50, true) {
            @Override
            protected Control createControl1(Composite parent) {
                master = createMaster(parent);
                return master.getControl();
            }

            @Override
            protected Control createControl2(Composite parent) {
                return new CoolBarComposite(parent, SWT.NONE) {
                    @Override
                    protected Control createUI(Composite parent) {
                        // Styles: CLOSE, TOP, BOTTOM, FLAT, BORDER, SINGLE, MULTI
                        detailsFolder = new CTabFolder(parent, SWT.BOTTOM | SWT.FLAT);
                        detailsFolder.setLayoutData(UIUtil.createGridData());
                        adjustDetails(null);
                        detailsFolder.addSelectionListener(new SelectionAdapter() {
                            @Override
                            public void widgetSelected(SelectionEvent e) {
                                String title = detailsFolder.getSelection().getText();
                                int detailIndex = indexOf(detailItems, title);
                                if (detailIndex != currentDetailIndex) {
                                    currentDetailIndex = detailIndex;
                                    updateCoolBar();
                                }
                            }
                        });

                        return detailsFolder;
                    }

                    @Override
                    protected void fillCoolBar(IContributionManager manager) {
                        MasterDetailsView.this.fillCoolBar(manager);
                        manager.add(new RefreshAction());
                    }
                };
            }
        };

        sash.setVertical(true);
        setCurrentViewer(master);
        master.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                try {
                    masterSelectionChanged(event);
                } catch (Error ex) {
                    OM.LOG.error(ex);
                    throw ex;
                } catch (RuntimeException ex) {
                    OM.LOG.error(ex);
                    throw ex;
                }
            }
        });

        return sash;
    }

    @Override
    protected void fillLocalPullDown(IMenuManager manager) {
        super.fillLocalPullDown(manager);
        manager.add(new Separator("group1")); //$NON-NLS-1$
        manager.add(new SashLayoutAction.LayoutMenu(sash));
        manager.add(new Separator("group2")); //$NON-NLS-1$
        manager.add(new RefreshAction());
    }

    protected void masterSelectionChanged(SelectionChangedEvent event) {
        IStructuredSelection selection = (IStructuredSelection) master.getSelection();
        Object masterElement = selection.getFirstElement();
        adjustDetails(masterElement);
    }

    protected void adjustDetails(Object masterElement) {
        if (ObjectUtil.equals(masterElement, currentMasterElement)) {
            return;
        }

        // Temporarily remember old values
        String oldDetailTitle = detailItems == null || currentDetailIndex < 0 ? null
                : detailItems[currentDetailIndex].getText();
        StructuredViewer[] oldDetails = details;
        CTabItem[] oldDetailItems = detailItems;

        // Initialize new values
        detailTitles = getDetailTitles(masterElement);
        details = new StructuredViewer[detailTitles.length];
        detailItems = new CTabItem[detailTitles.length];

        for (int i = 0; i < detailTitles.length; i++) {
            String title = detailTitles[i];
            int oldIndex = indexOf(oldDetailItems, title);
            if (oldIndex != -1) {
                details[i] = oldDetails[oldIndex];
                oldDetailItems[oldIndex].setControl(null);
                oldDetailItems[oldIndex].dispose();
                oldDetailItems[oldIndex] = null;
            } else {
                details[i] = createDetail(detailsFolder, title);
            }

            detailItems[i] = new CTabItem(detailsFolder, SWT.NONE, i);
            detailItems[i].setText(title);
            detailItems[i].setControl(details[i].getControl());
        }

        // Cleanup
        if (oldDetailItems != null) {
            for (CTabItem item : oldDetailItems) {
                if (item != null) {
                    item.dispose();
                }
            }
        }

        currentMasterElement = masterElement;
        for (StructuredViewer viewer : details) {
            setDetailInput(viewer, masterElement);
        }

        currentDetailIndex = indexOf(detailItems, oldDetailTitle);
        if (currentDetailIndex == -1 && details.length > 0) {
            currentDetailIndex = 0;
        }

        if (currentDetailIndex != -1) {
            detailsFolder.setSelection(currentDetailIndex);
        }
    }

    protected void setDetailInput(StructuredViewer viewer, Object input) {
        if (input != viewer.getInput()) {
            viewer.setInput(input);
        }
    }

    protected void fillCoolBar(IContributionManager manager) {
    }

    protected abstract StructuredViewer createMaster(Composite parent);

    protected abstract StructuredViewer createDetail(Composite parent, String title);

    protected abstract String[] getDetailTitles(Object masterElement);

    public static int indexOf(CTabItem[] items, String title) {
        if (items != null) {
            for (int i = 0; i < items.length; i++) {
                CTabItem item = items[i];
                if (item != null && ObjectUtil.equals(item.getText(), title)) {
                    return i;
                }
            }
        }

        return -1;
    }

    /**
     * @author Eike Stepper
     */
    protected final class RefreshAction extends SafeAction {
        public RefreshAction() {
            super(Messages.getString("MasterDetailsView_2"), Messages.getString("MasterDetailsView_3"), //$NON-NLS-1$ //$NON-NLS-2$
                    OM.getImageDescriptor("icons/full/etool16/refresh.gif")); //$NON-NLS-1$
        }

        @Override
        protected void safeRun() throws Exception {
            StructuredViewer viewer = getCurrentViewer();
            if (viewer != null) {
                viewer.refresh();
            }
        }
    }
}