`

eclipse RCP 模仿win7资源管理器地址栏功能

 
阅读更多

本文实现效果及其工具下载地址:http://sourceforge.net/projects/filetools/

 

windows7/8的资源管理器个人觉得比较便利的还属地址栏,在定位资源位置时非常方面。见下图:



 

当窗口大小改变,或地址栏的长度过长时,地址栏会自动隐藏头部。这是一个优点,但同时也是一个缺点。大多数时候,我们需要点击多次才能回到地址头部。而显示出来的那一部分,恰恰是不经常使用的。所以,我想对其进行改进,使地址栏可以达到:

  • 能够显示全部地址栏信息,在长度大导致空间不足时显示尽量多的位置信息,可以隐藏文本信息,但应该显示相应标志指示父文件夹和根目录;

初步实现的效果如图:

 

 

实现这个效果并不困难。第一种方法是是通过layout来实现。在swt中,常见的rowlayout实现的就是类似的效果,我们可以通过修改rowlayout来达到目的,并达到支持水平和垂直布局。第二种方法是调用jdt里面的BreadcrumbView,做适当修改就可以。

第一种方法的实现(详见附件,里面有源码和测试代码):

/* AutoAdjustRowLayout.java 
 * Copyright (c) 2013 by Brook Tran
 * All rights reserved.
 * 
 * The copyright of this software is own by the authors.
 * You may not use, copy or modify this software, except
 * in accordance with the license agreement you entered into 
 * with the copyright holders. For details see accompanying license
 * terms.
 */
package org.jeelee.filemanager.ui.breadcrumb;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.RowData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Layout;

/**
 * <B>AutoAdjustRowLayout</B>
 * extends from {@link org.eclipse.swt.layout.RowLayout} 
 * @author Brook Tran. Email: <a href="mailto:Brook.Tran.C@gmail.com">Brook.Tran.C@gmail.com</a>
 * @since org.jeelee.filemanager 2013-1-9 created
 */
public class BreadcrumbLayout extends Layout{

	/**
	 * type specifies whether the layout places controls in rows or 
	 * columns.
	 * 
	 * The default value is HORIZONTAL.
	 * 
	 * Possible values are: <ul>
	 *    <li>HORIZONTAL: Position the controls horizontally from left to right</li>
	 *    <li>VERTICAL: Position the controls vertically from top to bottom</li>
	 * </ul>
	 * 
	 * @since 2.0
	 */
	public int type = SWT.HORIZONTAL | SWT.RIGHT_TO_LEFT;
	
	/**
	 * marginWidth specifies the number of pixels of horizontal margin
	 * that will be placed along the left and right edges of the layout.
	 *
	 * The default value is 0.
	 * 
	 * @since 3.0
	 */
 	public int marginWidth = 0;
 	
	/**
	 * marginHeight specifies the number of pixels of vertical margin
	 * that will be placed along the top and bottom edges of the layout.
	 *
	 * The default value is 0.
	 * 
	 * @since 3.0
	 */
 	public int marginHeight = 0;

	/**
	 * spacing specifies the number of pixels between the edge of one cell
	 * and the edge of its neighbouring cell.
	 *
	 * The default value is 3.
	 */
	public int spacing = 3;
	 		
	/**
	 * pack specifies whether all controls in the layout take
	 * their preferred size.  If pack is false, all controls will 
	 * have the same size which is the size required to accommodate the 
	 * largest preferred height and the largest preferred width of all 
	 * the controls in the layout.
	 *
	 * The default value is true.
	 */
	public boolean pack = true;
	
	/**
	 * fill specifies whether the controls in a row should be
	 * all the same height for horizontal layouts, or the same
	 * width for vertical layouts.
	 *
	 * The default value is false.
	 * 
	 * @since 3.0
	 */
	public boolean fill = false;


	/**
	 * marginLeft specifies the number of pixels of horizontal margin
	 * that will be placed along the left edge of the layout.
	 *
	 * The default value is 3.
	 */
	public int marginLeft = 3;

	/**
	 * marginTop specifies the number of pixels of vertical margin
	 * that will be placed along the top edge of the layout.
	 *
	 * The default value is 3.
	 */
	public int marginTop = 3;

	/**
	 * marginRight specifies the number of pixels of horizontal margin
	 * that will be placed along the right edge of the layout.
	 *
	 * The default value is 3.
	 */
	public int marginRight = 3;

	/**
	 * marginBottom specifies the number of pixels of vertical margin
	 * that will be placed along the bottom edge of the layout.
	 *
	 * The default value is 3.
	 */
	public int marginBottom = 3;

	
	public BreadcrumbLayout() {
	}
	
	public BreadcrumbLayout (int type) {
		this.type = type;
	}
	@Override
	protected void layout (Composite composite, boolean flushCache) {
		Rectangle clientArea = composite.getClientArea ();
		if ((type & SWT.HORIZONTAL) == SWT.HORIZONTAL) {
			layoutHorizontal (composite, true,  clientArea.width, flushCache);
		} else {
			layoutVertical (composite, true, clientArea.height, flushCache);
		}
	}
	@Override
	protected Point computeSize (Composite composite, int wHint, int hHint, boolean flushCache) {
		Point extent;
		if ((type & SWT.HORIZONTAL) == SWT.HORIZONTAL) {
			extent = layoutHorizontal (composite, false,  wHint, flushCache);
		} else {
			extent = layoutVertical (composite, false,  hHint, flushCache);
		}
		if (wHint != SWT.DEFAULT) {
			extent.x = wHint;
		}
		if (hHint != SWT.DEFAULT) {
			extent.y = hHint;
		}
		return extent;
	}
	
	Point layoutHorizontal (Composite composite, boolean move, int width, boolean flushCache) {
		Control [] children = composite.getChildren ();
		int count = 0;
		for (int i=0; i<children.length; i++) {
			Control control = children [i];
			RowData data = (RowData) control.getLayoutData ();
			if (data == null || !data.exclude) {
				children [count++] = children [i];
			} 
		}
		if (count == 0) {
			return new Point (marginLeft + marginWidth * 2 + marginRight, marginTop + marginHeight * 2 + marginBottom);
		}
		

		
		int startIndex = 0;
		if( ( type & SWT.RIGHT_TO_LEFT) == SWT.RIGHT_TO_LEFT){
			startIndex = count;
			int maxWidth = marginLeft + marginWidth + marginRight + marginWidth;
//			marginRight + marginLeft +marginWidth  ;
			while(startIndex>0 && maxWidth<width){
				Control child = children [startIndex-1];
				Point size = computeSize (child, flushCache);
				maxWidth += size.x +spacing  + marginWidth;
				startIndex--;
			}
			startIndex = adjust(move, children, count, startIndex);
		}
			
		int childWidth = 0, childHeight = 0, maxHeight = 0;
		// get max width & height
		if (!pack) {
			for (int i=startIndex; i<count; i++) {
				Control child = children [i];
				Point size = computeSize (child, flushCache);
				childWidth = Math.max (childWidth, size.x);
				childHeight = Math.max (childHeight, size.y);
			}
			maxHeight = childHeight;
		}
		
		int clientX = 0, clientY = 0;
		if (move) {
			Rectangle rect = composite.getClientArea ();
			clientX = rect.x;
			clientY = rect.y;
		}
		
		Rectangle [] bounds = null;
		if (move && (fill )) {
			bounds = new Rectangle [count];
		}
		int maxX = 0, x = marginLeft + marginWidth, y = marginTop + marginHeight;
		
		
		for (int i=startIndex; i<count; i++) {
			Control child = children [i];
			if (pack) {
				Point size = computeSize (child, flushCache);
				childWidth = size.x;
				childHeight = size.y;
			}
			if (pack || fill ) {
				maxHeight = Math.max (maxHeight, childHeight);
			}
			if (move) {
				int childX = x + clientX, childY = y + clientY;
				if ( fill ) {
					bounds [i] = new Rectangle (childX, childY, childWidth, childHeight);
				} else {
					child.setBounds (childX, childY, childWidth, childHeight);
				}
			}
			x += spacing + childWidth;
			maxX = Math.max (maxX, x);
		}
		maxX = Math.max (clientX + marginLeft + marginWidth, maxX - spacing);
			maxX += marginRight + marginWidth;
		if (move && (fill)) {
			for (int i=startIndex; i<count; i++) {
					if (fill) {
						bounds [i].height = maxHeight;
					} 
				children [i].setBounds (bounds [i]);
			}
		}
		return new Point (maxX, y + maxHeight + marginBottom + marginHeight);
	}

	Point layoutVertical (Composite composite, boolean move,int height, boolean flushCache) {
		Control [] children = composite.getChildren ();
		int count = 0;
		for (int i=0; i<children.length; i++) {
			Control control = children [i];
			RowData data = (RowData) control.getLayoutData ();
			if (data == null || !data.exclude) {
				children [count++] = children [i];
			} 
		}
		if (count == 0) {
			return new Point (marginLeft + marginWidth * 2 + marginRight, marginTop + marginHeight * 2 + marginBottom);
		}
		

		int startIndex = 0;
		if( ( type & SWT.RIGHT_TO_LEFT) == SWT.RIGHT_TO_LEFT){
			startIndex = count;
			int maxHeight = marginTop + marginHeight+ marginBottom +marginHeight  ;
			while(startIndex>0 && maxHeight<height){
				Control child = children [startIndex-1];
				Point size = computeSize (child, flushCache);
				maxHeight += size.y +spacing + marginTop +marginHeight;
				startIndex--;
			}
			startIndex = adjust(move, children, count, startIndex);
		}
		
		
		
		int childWidth = 0, childHeight = 0, maxWidth = 0;
		if (!pack) {
			for (int i=startIndex; i<count; i++) {
				Control child = children [i];
				Point size = computeSize (child, flushCache);
				childWidth = Math.max (childWidth, size.x);
				childHeight = Math.max (childHeight, size.y);
			}
			maxWidth = childWidth;
		}
		int clientX = 0, clientY = 0;
		if (move) {
			Rectangle rect = composite.getClientArea ();
			clientX = rect.x;
			clientY = rect.y;
		}
		Rectangle [] bounds = null;
		if (move && (fill)) {
			bounds = new Rectangle [count];
		}
		int maxY = 0, x = marginLeft + marginWidth, y = marginTop + marginHeight;
		for (int i=startIndex; i<count; i++) {
			Control child = children [i];
			if (pack) {
				Point size = computeSize (child, flushCache);
				childWidth = size.x;
				childHeight = size.y;
			}
			if (pack || fill ) {
				maxWidth = Math.max (maxWidth, childWidth);
			}
			if (move) {
				int childX = x + clientX, childY = y + clientY;
				if ( fill ) {
					bounds [i] = new Rectangle (childX, childY, childWidth, childHeight);
				} else {
					child.setBounds (childX, childY, childWidth, childHeight);
				}
			}
			y += spacing + childHeight;
			maxY = Math.max (maxY, y);
		}
		maxY = Math.max (clientY + marginTop + marginHeight, maxY - spacing);
		if (move && (fill )) {
			for (int i=startIndex; i<count; i++) {
				children [i].setBounds (bounds [i]);
			}
		}
		return new Point (x + maxWidth + marginRight + marginWidth, maxY);
	}

	private int adjust(boolean move, Control[] children, int count,
			int startIndex) {
		if (startIndex > 0) {
			startIndex++;
		}
		if(startIndex > count){
			startIndex--;
		}
		
		if(move){
			Rectangle hide = new Rectangle(0, 0, 0, 0);
			for(int i=0;i<startIndex;i++){
//				children[i].setVisible(false);
				children[i].setBounds(hide);
			}
		}
		return startIndex;
	}


	Point computeSize (Control control, boolean flushCache) {
		int wHint = SWT.DEFAULT, hHint = SWT.DEFAULT;
		RowData data = (RowData) control.getLayoutData ();
		if (data != null) {
			wHint = data.width;
			hHint = data.height;
		}
		return control.computeSize (wHint, hHint, flushCache);
	}
	
	
	
	@Override
	protected boolean flushCache (Control control) {
		return true;
	}

	String getName () {
		String string = getClass ().getName ();
		int index = string.lastIndexOf ('.');
		if (index == -1) {
			return string;
		}
		return string.substring (index + 1, string.length ());
	}
	@Override
	public String toString () {
	 	String string = getName ()+" {";
	 	string += "type="+((type != SWT.HORIZONTAL) ? "SWT.VERTICAL" : "SWT.HORIZONTAL")+" ";
	 	if (marginWidth != 0) {
			string += "marginWidth="+marginWidth+" ";
		}
	 	if (marginHeight != 0) {
			string += "marginHeight="+marginHeight+" ";
		}
	 	if (marginLeft != 0) {
			string += "marginLeft="+marginLeft+" ";
		}
	 	if (marginTop != 0) {
			string += "marginTop="+marginTop+" ";
		}
	 	if (marginRight != 0) {
			string += "marginRight="+marginRight+" ";
		}
	 	if (marginBottom != 0) {
			string += "marginBottom="+marginBottom+" ";
		}
	 	if (spacing != 0) {
			string += "spacing="+spacing+" ";
		}
		string += "pack="+pack+" ";
		string += "fill="+fill+" ";
		string = string.trim();
		string += "}";
	 	return string;
	}
	
}

 
 实现效果见下图。其中,第一栏是地址栏的模拟实现,这个会隐藏根目录和父级目录,只显示最多子节点。


 第二种方法相对比较简单,像使用普通view一样调用BreadcrumbView,设置LabelProvider和ContentProvider就可以了。

	class FilePathBreadcrumViewer extends BreadcrumbViewer{
		private FileFilterDelegate fFilter;
		public FilePathBreadcrumViewer(FileFilterDelegate fileFilter,
				Composite parent, int style) {
			super(parent, style);
			fFilter=fileFilter;
		}

		@Override
		protected void configureDropDownViewer(TreeViewer viewer, Object input) {
			viewer.setLabelProvider(new FileDelegateLableProvider());
			viewer.setContentProvider(new FileDelegateTreeContentProvider(fFilter));
		}
	}

 

 实现的效果:

 

 

 

 

  • 大小: 20.6 KB
  • 大小: 12 KB
  • 大小: 3.6 KB
4
2
分享到:
评论
2 楼 yunchow 2013-04-24  
luoyu-ds 写道
我是来看博主的头像的

+1
1 楼 luoyu-ds 2013-04-23  
我是来看博主的头像的

相关推荐

    Eclipse RCP 软件打包发布方法

    Eclipse Rich Client Platform (RCP) 是一个强大的框架,用于构建桌面应用程序。它提供了一整套工具和功能,使得开发者可以构建出具有丰富用户界面的应用。在开发完成后,我们需要将这些应用打包并发布,以便用户...

    Eclipse rcp深入浅出中英文版及配套代码

    2. **工作台(Workbench)**:Eclipse RCP的核心组件,负责管理窗口、视图和编辑器。理解工作台的工作原理对于构建用户界面至关重要。 3. **模型-视图-控制器(MVC)**:Eclipse RCP遵循MVC设计模式,分离了数据...

    EclipseRCP教程

    3. Editor:Eclipse RCP 的编辑器视图,提供了文本编辑和表单编辑功能。 六、Eclipse RCP 的交互机制 Eclipse RCP 的交互机制是指视图之间的交互机制,包括: 1. 事件处理机制:Eclipse RCP 的事件处理机制,提供...

    Eclipse RCP.pdf清晰版

    **Eclipse RCP**(Rich Client Platform)是一种构建丰富客户端应用程序的框架,它利用Eclipse平台的强大功能来创建高度定制化的桌面应用程序。通过RCP,开发者能够专注于业务逻辑而非繁琐的界面设计,极大地提高了...

    Eclipse Rcp

    RCP应用通常拥有和Eclipse类似的外观与操作体验,例如动态的菜单栏(Menubar)、工具栏(Toolbar)、编辑器(Editor)、视图(View)、工作台窗口(WorkbenchWindow)以及工作区(WorkSpace)等。这些组件共同构成了...

    eclipse rcp应用系统开发方法与实战源代码.zip

    6. **国际化和本地化**:Eclipse RCP支持多语言环境,开发者需要了解如何实现应用程序的国际化和本地化,包括资源文件的处理和语言切换机制。 7. **源代码实践**:压缩包中的源代码提供了实际的开发示例,通过分析...

    eclipse RCP mp3工程

    7. **学习资源**:这个项目对于想要学习Eclipse RCP开发的初学者来说是一个宝贵的实例,他们可以从源代码中学习如何结合Eclipse RCP和MP3处理技术。 综上所述,"eclipse RCP mp3工程"不仅是一个实用的音频处理应用...

    EclipseRcp 例子程序

    2. **工作台(Workbench)**:工作台是Eclipse RCP应用程序的中心,负责管理窗口、视图、编辑器等元素。开发者可以自定义工作台布局,例如添加新的视图或编辑器。 3. **视图(View)**:视图是用户界面中显示特定...

    Eclipse RCP培训.zip

    8. **模型-视图-控制器(MVC)**:Eclipse RCP遵循MVC设计模式,模型负责数据管理,视图负责显示,控制器处理用户输入和模型-视图间的交互。 9. **透视图(Perspective)**:透视图是工作台的一种布局,可以包含多...

    Eclipse RCP 插件开发指南

    通过使用Eclipse RCP,开发者可以创建高度可定制和扩展的应用程序,这些应用不仅具有强大的功能,而且还能与其他Eclipse插件无缝集成。 ##### Eclipse Workbench Eclipse Workbench 是 Eclipse RCP 的核心组成部分...

    eclipse RCP开发的编辑器

    本文将深入探讨如何利用Eclipse RCP进行编辑器开发,结合提供的描述,我们将分享一个初学者在学习RCP后完成的小程序案例。 首先,我们需要了解Eclipse RCP的核心概念。RCP是Eclipse IDE的底层架构,它提供了构建可...

    Eclipse RCP 属性编辑器实例

    Eclipse RCP(Rich Client Platform)是一个开源框架,用于构建功能丰富的桌面应用程序。它提供了丰富的用户界面组件和灵活的插件架构,使得开发者能够轻松创建复杂的软件应用。在这个"属性编辑器实例"中,我们将...

    Eclipse RCP开发详解

    Eclipse RCP允许开发者创建功能丰富的、可扩展的应用程序,这些应用程序拥有与Eclipse集成开发环境相同级别的质量和用户体验。在"**Eclipse RCP开发详解**"中,我们将深入探讨这个主题,帮助你快速掌握Eclipse RCP...

    ECLIPSE+RCP应用系统开发方法与实战(PDF 高岗著)

    Eclipse RCP是Eclipse IDE的一部分,它提供了一个框架,使得开发者可以构建功能丰富的、可定制的桌面应用程序。以下是对该书可能涉及的知识点的详细阐述: 1. **Eclipse RCP基础**:首先,书中会介绍Eclipse RCP的...

    documents about Eclipse RCP

    1. **Eclipse RCP基础**:首先,文章可能会介绍Eclipse RCP的基本概念,包括它的设计理念、架构和主要组件,如工作台(Workbench)、视图(Views)、编辑器(Editors)和透视图(Perspectives)。 2. **插件系统**...

    eclipse RCP Plug-in开发自学教程.pdf

    eclipse RCP Plug-in开发自学教程 eclipse RCP(Rich Client Platform)是一种基于eclipse的插件式开发平台,允许开发者使用eclipse结构风格设计弹性的可扩展的应用程序。RCP插件式开发方式可以重用eclipse中的方法...

    Eclipse Rcp comon Navigator demo

    1. **Navigator Model**:这是Common Navigator的核心,负责管理资源的层次结构。你可以通过实现`INavigatorModel`接口来定制自己的模型,或者使用默认的`WorkbenchNavigatorModel`。 2. **Navigator Content ...

    Eclipse RCP详细教程

    ### Eclipse RCP 详细教程 #### 1. 富客户端平台 ##### 1.1. 概述 Eclipse RCP(Rich Client Platform)是一种基于Java的框架,它允许开发者构建高度可定制和可扩展的桌面应用。这些应用通常具有丰富的用户界面,...

    菜鸟EclipseRCP学习之路

    2. **工作台(Workbench)**:Eclipse RCP的核心组件,负责管理窗口、视图、编辑器等用户界面元素。 3. **视图(Views)和编辑器(Editors)**:视图用于显示信息,编辑器用于处理用户交互和数据编辑,它们可以通过...

Global site tag (gtag.js) - Google Analytics