• RCP:美化基于eclipse3.7.2的RCP界面


    从e4开始,eclipse rcp界面具备了深度自定义的能力。

    但是在eclipse3.7.2上,几乎没有提供能够用于修改界面的外部接口。

    这里介绍一种方式来自定义你自己的eclipse rcp。

    先看如下对比图:

    可以看到有如下不同:

    1、整体风格扁平化了,没有沿用win7的玻璃外框

    2、横向的Menu被去掉了,整合到了左上角的按钮

    3、视图的签页扁平化了

    这只是一些示例,学习了以下方法,我们可以做更多的深度定制。

    首先我们需要知道eclipse的工作台结构。

    我们在创建一个eclipse rcp的时候,必然会用到Application,我们来看一下eclipse提供的IDEApplication这个类的start方法,注意123行

    int returnCode = PlatformUI.createAndRunWorkbench(display,
                        new IDEWorkbenchAdvisor(processor));

    观察IDEWorkbenchAdvisor可知,Workbench的创建被该类所代理了。

    这里我们需要了解以下几个类:

    Workbench 工作台(模型)
    WorkbenchAdvisor 管理工作台生命周期
    WorkbenchWindowAdvisor 提供ui配置,管理ui生命周期
    WorkbechWindowConfigurer 配置保存类
    WorbenchWindow 工作台UI(视图),基于SWT的界面类,实际上的RCP界面容器

    于是,我们可以知道,只要能重写自己的WorbenchWindow,就能够达成目标。方式如下:

    public class AimWorkbenchAdvisor extends IDEWorkbenchAdvisor {
    
        public AimWorkbenchAdvisor(DelayedEventsProcessor processor) {
            super(processor);
            Tweaklets.setDefault(WorkbenchImplementation.KEY,
                    new AimWorkbench3xImplementation());
        }
    
        public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(
                IWorkbenchWindowConfigurer configurer) {
            return new AimWorkbenchWindowAdvisor(this, configurer);
        }
    
    }

    1、提供一个AimWorkbenchAdvisor的子类,用于替换IDEApplication中的IDEWorkbenchAdvisor实例。

    2、替换WorkbenchWindow,通过Tweaklets.setDefault这个静态方法调用来实现

    public class AimWorkbench3xImplementation extends Workbench3xImplementation {
    
        /*
         * (non-Javadoc)
         * 
         * @see
         * org.eclipse.ui.internal.tweaklets.WorkbenchImplementation#createWBW(int)
         */
        public WorkbenchWindow createWorkbenchWindow(int newWindowNumber) {
    //        return AimWorkbenchFrame.getInstance(newWindowNumber);
            return new AimWorkbenchWindow(newWindowNumber);
        }
    
    }


    3、(可选)提供一个新的AimWorkbenchWindowAdvisor,用于屏蔽menu、perspectiveBar等操作。代码如下:

    public class AimWorkbenchWindowAdvisor extends IDEWorkbenchWindowAdvisor {
    
        public AimWorkbenchWindowAdvisor(IDEWorkbenchAdvisor wbAdvisor,
                IWorkbenchWindowConfigurer configurer) {
            super(wbAdvisor, configurer);
        }
    
        public void preWindowOpen() {
            super.preWindowOpen();
            IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
            configurer.setShowMenuBar(false);
            configurer.setShowPerspectiveBar(false);
        }
    }


    完成了以上,我们就具备了自定义WorkbenchWindow的能力。

    如果你不需要对RCP的外框、布局等进行修改,到了这一步其实就已经完成了。

    如果希望深入定制,则需要更多知识。

    首先需要学习TrimLayout,eclipse使用它作为基本布局,TrimLayout根据每个控件的ID,来针对性的排布。

    主要分为四个部分,top,left,right,bottom

    对TrimLayout进行改造,则可以重新布局。

    重写WorkbenchWindow#createDefaultContents方法

    在调用super.createDefaultContents之后,为shell重新设置一个你自己的TrimLayout

    比如:

    package cn.com.agree.ide.aim.product.ui.layout;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    
    import org.eclipse.jface.preference.IPreferenceStore;
    import org.eclipse.swt.SWT;
    import org.eclipse.swt.events.DisposeEvent;
    import org.eclipse.swt.events.DisposeListener;
    import org.eclipse.swt.graphics.Point;
    import org.eclipse.swt.graphics.Rectangle;
    import org.eclipse.swt.widgets.Composite;
    import org.eclipse.swt.widgets.Control;
    import org.eclipse.swt.widgets.Display;
    import org.eclipse.ui.IWorkbenchPreferenceConstants;
    import org.eclipse.ui.PlatformUI;
    import org.eclipse.ui.internal.layout.IWindowTrim;
    import org.eclipse.ui.internal.layout.LayoutUtil;
    import org.eclipse.ui.internal.layout.SizeCache;
    import org.eclipse.ui.internal.layout.TrimArea;
    import org.eclipse.ui.internal.layout.TrimCommonUIHandle;
    import org.eclipse.ui.internal.layout.TrimDescriptor;
    import org.eclipse.ui.internal.layout.TrimLayout;
    import org.eclipse.ui.internal.layout.TrimToolBarBase;
    
    /**
     * @author caiyu
     * @date 2014-12-20
     */
    @SuppressWarnings({ "restriction", "rawtypes" })
    public class AimTrimLayout extends TrimLayout {
    
        /**
         * Trim area ID.
         */
        public static final Integer TOP_ID = new Integer(TOP);
        /**
         * Trim area ID.
         */
        public static final Integer BAR_ID = new Integer(SWT.BAR);
    
        /**
         * Trim area ID.
         */
        public static final Integer BOTTOM_ID = new Integer(BOTTOM);
    
        /**
         * Trim area ID.
         */
        public static final Integer LEFT_ID = new Integer(LEFT);
        public static int ICON = new Integer(334);
        /**
         * Trim area ID.
         */
        public static final Integer ICON_ID = new Integer(ICON);
    
        /**
         * Trim area ID.
         */
        public static final Integer RIGHT_ID = new Integer(RIGHT);
    
        /**
         * Trim area ID.
         */
        public static final Integer NONTRIM_ID = new Integer(NONTRIM);
        /**
         * Trim area ID.
         */
        public static final Integer BORDER_ID = new Integer(SWT.BORDER);
    
        /**
         * IDs for the current trim areas we support.
         */
        private static final int[] TRIM_ID_INFO = { LEFT, RIGHT, TOP, BOTTOM,
                SWT.BAR, SWT.BORDER, ICON };
        public static int TOP_ANCHOR;
    
        private SizeCache centerArea = new SizeCache();
    
        /**
         * Map of TrimAreas by IDs.
         */
        private Map fTrimArea = new HashMap();
    
        /**
         * Map of TrimDescriptors by IDs.
         */
        private Map fTrimDescriptors = new HashMap();
    
        private boolean trimLocked;
    
        private HashMap preferredLocationMap = new HashMap();
    
        /**
         * Creates a new (initially empty) trim layout.
         */
        public AimTrimLayout() {
            // Determine whether or not the trim is 'locked'
            final IPreferenceStore store = PlatformUI.getPreferenceStore();
            trimLocked = store.getBoolean(IWorkbenchPreferenceConstants.LOCK_TRIM);
    
            createTrimArea(ICON_ID, ICON_ID.toString());
            createTrimArea(BAR_ID, BAR_ID.toString());
            createTrimArea(TOP_ID, TOP_ID.toString());
            createTrimArea(BOTTOM_ID, BOTTOM_ID.toString());
            createTrimArea(LEFT_ID, LEFT_ID.toString());
            createTrimArea(RIGHT_ID, RIGHT_ID.toString());
        }
    
        private void createTrimArea(Integer id, String displayName) {
            TrimArea area = new AimTrimArea(id.intValue(), displayName);
            fTrimArea.put(id, area);
        }
    
        /**
         * Returns the location of the given trim control. For example, returns
         * SWT.LEFT if the control is docked on the left, SWT.RIGHT if docked on the
         * right, etc. Returns SWT.DEFAULT if the given control is not a trim
         * control.
         * 
         * @param trimControl
         *            control to query
         * @return The area ID of this control. If the control is not part of our
         *         trim, return SWT.DEFAULT.
         * @see #getAreaIds()
         */
        public int getTrimAreaId(Control trimControl) {
            TrimDescriptor desc = findTrimDescription(trimControl);
            if (desc != null) {
                return desc.getAreaId();
            }
            return SWT.DEFAULT;
        }
    
        /**
         * @param control
         *            new window trim to be added
         * @param areaId
         *            the area ID
         * @see #getAreaIds()
         * @deprecated
         */
        public void addTrim(IWindowTrim control, int areaId) {
            addTrim(areaId, control, null);
        }
    
        /**
         * 
         * @param trim
         *            new window trim to be added
         * @param areaId
         *            the area ID
         * @param beforeMe
         *            if null, the control will be inserted as the last trim widget
         *            on this side of the layout. Otherwise, the control will be
         *            inserted before the given widget.
         * @see #getAreaIds()
         * @deprecated
         */
        public void addTrim(IWindowTrim trim, int areaId, IWindowTrim beforeMe) {
            addTrim(areaId, trim, beforeMe);
        }
    
        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.ui.internal.layout.ITrimManager#addTrim(int,
         * org.eclipse.ui.internal.IWindowTrim)
         */
        public void addTrim(int areaId, IWindowTrim trim) {
            // If we're adding trim to the same side that it's
            // already on then don't change its order
            IWindowTrim insertBefore = null;
            List trimDescs = getAreaTrim(areaId);
            for (Iterator trimIter = trimDescs.iterator(); trimIter.hasNext();) {
                IWindowTrim curTrim = (IWindowTrim) trimIter.next();
                if (curTrim.getId().equals(trim.getId())) {
                    if (trimIter.hasNext()) {
                        insertBefore = (IWindowTrim) trimIter.next();
                    }
                }
            }
    
            addTrim(areaId, trim, insertBefore);
        }
    
        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.ui.internal.layout.ITrimManager#addTrim(int,
         * org.eclipse.ui.internal.IWindowTrim, org.eclipse.ui.internal.IWindowTrim)
         */
        public void addTrim(int areaId, IWindowTrim trim, IWindowTrim beforeMe) {
            TrimArea area = (TrimArea) fTrimArea.get(new Integer(areaId));
            if (area == null) {
                return;
            }
            // remove the trim from the current layout
            removeTrim(trim);
    
            // Create a new trim descriptor for the new area...
            TrimDescriptor desc = new TrimDescriptor(trim, areaId);
    
            // If the trim can be relocated then add a dock ing handle
            boolean isAlreadyAHandle = trim instanceof TrimToolBarBase;
            if (!trimLocked && trim.getValidSides() != SWT.NONE
                    && !isAlreadyAHandle) {
                // Create a 'docking' handle to allow dragging the trim
                Composite dockingHandle = new TrimCommonUIHandle(this, trim, areaId);
                desc.setDockingCache(new SizeCache(dockingHandle));
            }
    
            // Add the trim control
            SizeCache cache = new SizeCache(trim.getControl());
            trim.getControl().setLayoutData(trim);
            desc.setCache(cache);
    
            // Add a dispose listener so we can clean up if the Client disposes the
            // trim
            trim.getControl().addDisposeListener(new DisposeListener() {
                public void widgetDisposed(DisposeEvent e) {
                    Control control = (Control) e.widget;
                    if (control.getLayoutData() instanceof IWindowTrim) {
                        IWindowTrim trim = (IWindowTrim) control.getLayoutData();
                        removeTrim(trim);
                        // forceLayout();
                    }
                }
            });
    
            // Add the new descriptor to the map
            fTrimDescriptors.put(desc.getId(), desc);
    
            // insert before behaviour, revisited
            if (beforeMe != null) {
                TrimDescriptor beforeDesc = (TrimDescriptor) fTrimDescriptors
                        .get(beforeMe.getId());
                if (beforeDesc != null && beforeDesc.getAreaId() == areaId) {
                    area.addTrim(desc, beforeDesc);
                } else {
                    area.addTrim(desc);
                }
            } else {
                area.addTrim(desc);
            }
        }
    
        /**
         * Force a layout of the trim
         */
        public void forceLayout() {
            removeDisposed();
    
            // we hack this by calling the LayoutUtil with the
            // first piece of trim that we find...(kludge!!)
            Iterator d = fTrimDescriptors.values().iterator();
            while (d.hasNext()) {
                TrimDescriptor desc = (TrimDescriptor) d.next();
                if (desc.getTrim().getControl() != null) {
                    LayoutUtil.resize(desc.getTrim().getControl());
                    return;
                }
            }
        }
    
        /*
         * (non-Javadoc)
         * 
         * @see
         * org.eclipse.ui.internal.layout.ITrimManager#removeTrim(org.eclipse.ui
         * .internal.IWindowTrim)
         */
        public void removeTrim(IWindowTrim toRemove) {
            TrimDescriptor desc = (TrimDescriptor) fTrimDescriptors.remove(toRemove
                    .getId());
            if (desc == null) {
                return;
            }
    
            TrimArea area = (TrimArea) fTrimArea.get(new Integer(desc.getAreaId()));
            if (area != null) {
                area.removeTrim(desc);
                desc.getCache().getControl().setLayoutData(null);
            }
    
            // If we had a trim UI handle then dispose it
            if (desc.getDockingCache() != null) {
                Control ctrl = desc.getDockingCache().getControl();
    
                // KLUDGE!! we'll leak a handle rather than losing the
                // mouse capture (for now...)
                ctrl.setVisible(false);
                // ctrl.dispose();
                desc.setDockingCache(null);
            }
        }
    
        /*
         * (non-Javadoc)
         * 
         * @see
         * org.eclipse.ui.internal.layout.ITrimManager#getTrim(java.lang.String)
         */
        public IWindowTrim getTrim(String id) {
            TrimDescriptor desc = (TrimDescriptor) fTrimDescriptors.get(id);
            if (desc != null) {
                return desc.getTrim();
            }
            return null;
        }
    
        /**
         * Removes any disposed widgets from this layout. This is still experimental
         * code.
         */
        private void removeDisposed() {
            Iterator a = fTrimArea.values().iterator();
            while (a.hasNext()) {
                TrimArea area = (TrimArea) a.next();
                Iterator d = area.getDescriptors().iterator();
                while (d.hasNext()) {
                    TrimDescriptor desc = (TrimDescriptor) d.next();
                    Control nextControl = desc.getTrim().getControl();
                    if (nextControl == null || nextControl.isDisposed()) {
                        // Remvoe the trim from the area's list (not the local copy)
                        area.removeTrim(desc);
    
                        // Remove it from the map
                        fTrimDescriptors.remove(desc.getId());
                    }
                }
            }
        }
    
        /**
         * We -can't- determine the correct size for the shell because of it's
         * underlying 'big lie' structure (i.e. many of the controls are created as
         * children of the shell and then we play a games than makes them -appear-
         * to be contained in a Control hoerarchy) and the fact that most of the UI
         * elements don't really exist until shown (meaning that the normal
         * 'computeSize' mechanism won't work).
         * 
         * See bug 166619 for details but we'll keep returning the current value for
         * legacy reasons...
         * 
         * @see org.eclipse.swt.widgets.Layout#computeSize(org.eclipse.swt.widgets.Composite,
         *      int, int, boolean)
         */
        protected Point computeSize(Composite composite, int wHint, int hHint,
                boolean flushCache) {
            return new Point(0, 0);
        }
    
        /*
         * (non-Javadoc)
         * 
         * @see
         * org.eclipse.swt.widgets.Layout#layout(org.eclipse.swt.widgets.Composite,
         * boolean)
         */
        protected void layout(Composite composite, boolean flushCache) {
            // long startTime = System.currentTimeMillis();
            removeDisposed();
    
            // get the actual trim areas
            TrimArea bar = (TrimArea) fTrimArea.get(BAR_ID);
            TrimArea top = (TrimArea) fTrimArea.get(TOP_ID);
            TrimArea bottom = (TrimArea) fTrimArea.get(BOTTOM_ID);
            TrimArea left = (TrimArea) fTrimArea.get(LEFT_ID);
            TrimArea right = (TrimArea) fTrimArea.get(RIGHT_ID);
    
            Rectangle clientArea = composite.getClientArea();
    
            TrimArea icon = (TrimArea) fTrimArea.get(ICON_ID);
            Control iconControl = null;
            Point iconSize = null;
            for (Object cache : icon.getCaches()) {
                if (cache instanceof SizeCache) {
                    iconControl = ((SizeCache) cache).getControl();
                    iconSize = iconControl.computeSize(0, 0);
                }
            }
    
            // Determine the amount of space necessary for the trim areas
            int trim_bar = bar.computeWrappedTrim(clientArea.width
                    - (iconSize == null ? 0 : iconSize.x - 10)) - 8;
            int trim_top = top.computeWrappedTrim(clientArea.width + trim_bar)
                    + trim_bar;
            int trim_bottom = bottom.computeWrappedTrim(clientArea.width);
    
            // The space left over after the top and bottom have been laid out
            // represents the 'fixed' dimension for the vertical trim
            int verticalMajor = clientArea.height - (trim_top + trim_bottom);
    
            // Lay out the left/ hhhright trim areas
            // int trim_left = left.computeWrappedTrim(verticalMajor);
            // int trim_right = right.computeWrappedTrim(verticalMajor);
            int trim_left = 1;
            int trim_right = 1;
    
            int trim_icon = 0;
            if (iconSize != null) {
                trim_icon = iconSize.x;
                iconControl.setBounds(clientArea.x - 1, clientArea.y - 2,
                        iconSize.x, iconSize.y);
            }
            // TODO Tile the trim into the allotted space
            bar.tileTrim(clientArea.x + trim_icon - 3, clientArea.y - 2,
                    clientArea.width);
            top.tileTrim(clientArea.x + trim_icon, clientArea.y + trim_bar + 2,
                    clientArea.width - trim_icon);
            bottom.tileTrim(clientArea.x - 2, clientArea.height - trim_bottom,
                    clientArea.width);
            left.tileTrim(clientArea.x, clientArea.y + trim_top, verticalMajor);
            right.tileTrim(clientArea.width - trim_right, clientArea.y + trim_top,
                    verticalMajor);
    
            // Lay out the center area in to the 'leftover' space
            if (centerArea.getControl() != null) {
                Control caCtrl = centerArea.getControl();
                caCtrl.setBounds(clientArea.x + trim_left, clientArea.y + trim_top,
                        clientArea.width - (trim_left + trim_right),
                        clientArea.height - (trim_top + trim_bottom));
            }
        }
    
        /**
         * Sets the widget that will occupy the central area of the layout.
         * Typically, this will be a composite that contains the main widgetry of
         * the application.
         * 
         * @param center
         *            control that will occupy the center of the layout, or null if
         *            none
         */
        public void setCenterControl(Control center) {
            centerArea.setControl(center);
        }
    
        /**
         * Returns the control in the center of this layout
         * 
         * @return the center area control.
         */
        public Control getCenterControl() {
            return centerArea.getControl();
        }
    
        /*
         * (non-Javadoc)
         * 
         * @see
         * org.eclipse.ui.internal.layout.ICachingLayout#flush(org.eclipse.swt.widgets
         * .Control)
         */
        public void flush(Control dirtyControl) {
            if (dirtyControl == centerArea.getControl()) {
                centerArea.flush();
            } else {
                TrimDescriptor desc = findTrimDescription(dirtyControl);
                if (desc != null) {
                    desc.flush();
                }
            }
        }
    
        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.ui.internal.layout.ITrimManager#getAreaIds()
         */
        public int[] getAreaIds() {
            return (int[]) TRIM_ID_INFO.clone();
        }
    
        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.ui.internal.layout.ITrimManager#getAreaTrim(int)
         */
        public List getAreaTrim(int areaId) {
            TrimArea area = (TrimArea) fTrimArea.get(new Integer(areaId));
            if (area == null) {
                return Collections.EMPTY_LIST;
            }
            return area.getTrims();
        }
    
        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.ui.internal.layout.ITrimManager#updateAreaTrim(int,
         * java.util.List, boolean)
         */
        public void updateAreaTrim(int id, List trim, boolean removeExtra) {
            TrimArea area = (TrimArea) fTrimArea.get(new Integer(id));
            if (area == null) {
                return;
            }
            List current = area.getTrims();
    
            // add back the trim ... this takes care of moving it
            // from one trim area to another.
            Iterator i = trim.iterator();
            while (i.hasNext()) {
                IWindowTrim t = (IWindowTrim) i.next();
                t.dock(id); // Ensure that the trim is properly oriented
                addTrim(id, t, null);
                current.remove(t);
            }
    
            if (removeExtra) {
                // if it wasn't removed from the current list, then it's extra
                // trim we don't need.
                i = current.iterator();
                while (i.hasNext()) {
                    IWindowTrim t = (IWindowTrim) i.next();
                    removeTrim(t);
                }
            }
        }
    
        /**
         * Return a trim area rectangle.
         * 
         * @param window
         *            the window that has the trim
         * @param areaId
         *            the side it's on
         * @return the area rectangle.
         * @since 3.2
         * @see #getAreaIds()
         */
        public Rectangle getTrimRect(Composite window, int areaId) {
            TrimArea area = getTrimArea(areaId);
            return window.getDisplay().map(window, null, area.getCurRect());
        }
    
        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.ui.internal.layout.ITrimManager#getAllTrim()
         */
        public List getAllTrim() {
            List trimList = new ArrayList(fTrimDescriptors.size());
    
            Iterator d = fTrimDescriptors.values().iterator();
            while (d.hasNext()) {
                TrimDescriptor desc = (TrimDescriptor) d.next();
                trimList.add(desc.getTrim());
            }
    
            return trimList;
        }
    
        /*
         * (non-Javadoc)
         * 
         * @see
         * org.eclipse.ui.internal.layout.ITrimManager#setTrimVisible(org.eclipse
         * .ui.internal.IWindowTrim, boolean)
         */
        public void setTrimVisible(IWindowTrim trim, boolean visible) {
            TrimDescriptor desc = findTrimDescription(trim.getControl());
    
            if (desc != null) {
                desc.setVisible(visible);
            }
        }
    
        /**
         * Find the trim descriptor for this control.
         * 
         * @param trim
         *            the Control to find.
         * @return the trim descriptor, or <code>null</code> if not found.
         * @since 3.2
         */
        private TrimDescriptor findTrimDescription(Control trim) {
            Iterator d = fTrimDescriptors.values().iterator();
            while (d.hasNext()) {
                TrimDescriptor desc = (TrimDescriptor) d.next();
                if (desc.getTrim().getControl() == trim) {
                    return desc;
                }
                if (desc.getDockingCache() != null
                        && desc.getDockingCache().getControl() == trim) {
                    return desc;
                }
            }
            return null;
        }
    
        /**
         * Return the trim area associated with the given id
         * 
         * @param areaId
         *            The id of the trim area to get
         * @return The TrimArea or <code>null</code> if the id is not found
         */
        public TrimArea getTrimArea(int areaId) {
            return (TrimArea) fTrimArea.get(new Integer(areaId));
        }
    
        /**
         * Remember the persisted locations for the trim. This allows the code to
         * site the trim in its preferred (i.e. cached) location on creation
         * 
         * @param areaId
         *            The id of the trim area being defined
         * @param preferredLocations
         *            A list of trim ID's
         */
        public void setPreferredLocations(int areaId, List preferredLocations) {
            preferredLocationMap.put(new Integer(areaId), preferredLocations);
        }
    
        /**
         * If the given id has a cached location return its preferred side
         * 
         * @param trimId
         *            The id of the trim to be tested
         * @return The areaId of a cached id or -1 if no cache info exists
         */
        public int getPreferredArea(String trimId) {
            Iterator keyIter = preferredLocationMap.keySet().iterator();
            while (keyIter.hasNext()) {
                Integer key = (Integer) keyIter.next();
                List areaList = (List) preferredLocationMap.get(key);
                if (areaList.contains(trimId))
                    return key.intValue();
            }
    
            return -1;
        }
    
        /**
         * If the given id has a cached location return an existing trim element
         * that it should be placed before (if any)
         * 
         * @param trimId
         *            The id of the trim to be tested
         * @return The trim to be inserted before or <code>null</code> if no cached
         *         info exists
         */
        public IWindowTrim getPreferredLocation(String trimId) {
            Iterator keyIter = preferredLocationMap.keySet().iterator();
            while (keyIter.hasNext()) {
                Integer key = (Integer) keyIter.next();
                List areaList = (List) preferredLocationMap.get(key);
                int index = areaList.indexOf(trimId);
                if (index != -1) {
                    // OK, find the first 'real' trim after this one
                    // This will be used as the 'beforeMe' parameter
                    // in the 'addTrim' call
                    for (int i = index + 1; i < areaList.size(); i++) {
                        String id = (String) areaList.get(i);
                        IWindowTrim trim = getTrim(id);
                        if (trim != null)
                            return trim;
                    }
                }
            }
    
            return null;
        }
    
        /**
         * Disables the controls associated with visible trim elements. This is only
         * used during long-running WorkbenchWindow operations to prevent users from
         * changing the environment while the operation (i.e. a long-running editor
         * 'save') is in progress.
         * 
         * The expected life-cycle is to first call this this method to disable any
         * visible trim (and caching the elements that had to be disabled) followed
         * by a call to 'enableTrim' passing in the list returned from this method.
         * 
         * @param ignoreMe
         *            Since the current UI has a disable button in the StatusLine we
         *            allow the caller to designate one piece of trim to ignore
         * 
         * @return The list of trim controls that were disabled during this call
         */
        public List disableTrim(IWindowTrim ignoreMe) {
            List disabledControls = new ArrayList();
    
            // Disable all the trim -except- for 'ignoreMe'
            List allTrim = getAllTrim();
            for (Iterator trimIter = allTrim.iterator(); trimIter.hasNext();) {
                IWindowTrim trim = (IWindowTrim) trimIter.next();
                if (ignoreMe == trim)
                    continue;
    
                Control ctrl = trim.getControl();
                if (ctrl == null || ctrl.isDisposed() || !ctrl.isVisible()
                        || !ctrl.isEnabled())
                    continue;
    
                ctrl.setEnabled(false);
                disabledControls.add(ctrl);
            }
    
            return disabledControls;
        }
    
        /**
         * Enables the controls in the list. This list is expected to be a
         * non-modified List as returned from a call to 'disableTrim'.
         * 
         * @param disabledControls
         *            The list of controls to enable
         */
        public void enableTrim(List disabledControls) {
            // Simply re-enable any controls in the list
            for (Iterator dcIter = disabledControls.iterator(); dcIter.hasNext();) {
                Control ctrl = (Control) dcIter.next();
    
                if (!ctrl.isDisposed() && !ctrl.isEnabled())
                    ctrl.setEnabled(true);
            }
        }
    }
    View Code


    TrimLayout并不适合继承,所以我copy了一份出来,加入了"Bar"区域和"ICON"区域

    以上 就完成了基本的改写。

  • 相关阅读:
    053587
    053586
    053585
    053584
    053583
    053582
    053581
    053580
    053579
    053578
  • 原文地址:https://www.cnblogs.com/anrainie/p/4191917.html
Copyright © 2020-2023  润新知