从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);
}
}
}

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

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

RCP:美化基于eclipse3.7.2的RCP界面的更多相关文章

  1. Vue.js – 基于 MVVM 实现交互式的 Web 界面

    Vue.js 是用于构建交互式的 Web  界面的库.它提供了 MVVM 数据绑定和一个可组合的组件系统,具有简单.灵活的 API.从技术上讲, Vue.js 集中在 MVVM 模式上的视图模型层,并 ...

  2. [置顶] 使用红孩儿工具箱完成基于Cocos2d-x的简单游戏动画界面

    [Cocos2d-x相关教程来源于红孩儿的游戏编程之路CSDN博客地址:http://blog.csdn.net/honghaier 红孩儿Cocos2d-X学习园地QQ3群:205100149,47 ...

  3. 分享一款基于aui框架的图文发布界面

    本文出自APICloud官方论坛, 感谢论坛版主 川哥哥 的分享. 分享一款基于aui框架的图文发布界面,可以添加多张图可以删除,类似qq空间发布说说,没做服务器后端,只演示前端操作.需要用到UIMe ...

  4. 循序渐进BootstrapVue,开发公司门户网站(1)---基于Bootstrap网站模板构建组件界面

    在前面随笔<使用BootstrapVue相关组件,构建Vue项目界面>概括性的介绍了BootstrapVue的使用过程,其实选用这个主要就是希望能够用来构建一些公司门户网站的内容,毕竟基于 ...

  5. 为基于OpenCV的图像处理程序编写界面—关于QT\MFC\CSharp的选择以及GOCW的介绍

            基于OpenCV编写图像处理项目,除了算法以外,比较重要一个问题就是界面设计问题.对于c++语系的程序员来说,一般来说有QT/MFC两种考虑.QT的确功能强大,特别是QML编写andr ...

  6. centos6.5环境基于conga的web图形化界面方式配置rhcs集群

    一.简介 RHCS 即 RedHat Cluster Suite ,中文意思即红帽集群套件.红帽集群套件(RedHat Cluter Suite, RHCS)是一套综合的软件组件,可以通过在部署时采用 ...

  7. 基于easyUI实现经典系统主界面

    此文章是基于 EasyUI+Knockout实现经典表单的查看.编辑 一. 相关文件介绍 1. home.jsp:系统主界面 <!DOCTYPE html PUBLIC "-//W3C ...

  8. 【4opencv】为基于OpenCV的图像处理程序编写界面—关于QT\MFC\CSharp的选择以及GOCW的介绍

            基于OpenCV编写图像处理项目,除了算法以外,比较重要一个问题就是界面设计问题.对于c++语系的程序员来说,一般来说有QT/MFC两种考虑.QT的确功能强大,特别是QML编写andr ...

  9. 基于angular2x+ng-bootstrap构建后台管理系统界面(干货)

    写在前面的话 近来公司要做一个后台管理系统,人手比较少,于是作为一个前端也参与进来,其实据我所知,大部分的公司还是后台自己捣鼓的. 在后台没有到位的情况下,前端应该使用什么技术也着实让我为难了一把.经 ...

随机推荐

  1. 使用cookie实现计数器功能

    思路是:若第一次访问,创建cookie.若访问次数大于一,则先读出cookie值赋给一个值,然后再重新写入cookie. <?php if(!isset($_COOKIE['num'])){ $ ...

  2. 第四章 使用Docker镜像和仓库

    第4章 使用Docker镜像和仓库 回顾: 回顾如何使用 docker run 创建最基本的容器 $sudo docker run -i -t --name another_container_mum ...

  3. json数据测试接口

    json数据测试接口:http://www.xiaoqiang.org/tools/JsonView/?1348068433

  4. 关于hover

    要想实现a:hover b{} 得到样式的话,a必须是b的父元素

  5. configure: error: no acceptable C compiler found in $PAT 的解决方案

    configure: error: no acceptable C compiler found in $PATH See `config.log' for more details.你的机器里没有安 ...

  6. How to copy remote computer files quickly to local computer

    if we want copy file from VM(Remote VM) to local computer. Always can not easy copy file so easy. no ...

  7. 用C语言关于学生管理系统的几种实现方法(一位数组,二维数组,指针,结构体)

    一位数组: #include <stdio.h> #include<string.h> #define N 5 void luru(float s[],int n); void ...

  8. spring-aop学习

     SpringAOP学习 author:luojie 1.  AOP中的基本概念 AOP的通用术语,并非spring java所特有.很遗憾AOP的术语不是特别的直观.但如果让Spring java来 ...

  9. eclipse js 引用跳转

    引用 http://stackoverflow.com/questions/24505993/the-resource-is-not-on-the-build-path-of-a-javascript ...

  10. out与ref的区别

    out与ref的区别  前者传参时不必初始化,后者需要初始化 int a,b; public void fName(out int a,out int b); fName(out a , out b) ...