本文实现效果及其工具下载地址: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)); } }
实现的效果:
相关推荐
Eclipse Rich Client Platform (RCP) 是一个强大的框架,用于构建桌面应用程序。它提供了一整套工具和功能,使得开发者可以构建出具有丰富用户界面的应用。在开发完成后,我们需要将这些应用打包并发布,以便用户...
2. **工作台(Workbench)**:Eclipse RCP的核心组件,负责管理窗口、视图和编辑器。理解工作台的工作原理对于构建用户界面至关重要。 3. **模型-视图-控制器(MVC)**:Eclipse RCP遵循MVC设计模式,分离了数据...
3. Editor:Eclipse RCP 的编辑器视图,提供了文本编辑和表单编辑功能。 六、Eclipse RCP 的交互机制 Eclipse RCP 的交互机制是指视图之间的交互机制,包括: 1. 事件处理机制:Eclipse RCP 的事件处理机制,提供...
**Eclipse RCP**(Rich Client Platform)是一种构建丰富客户端应用程序的框架,它利用Eclipse平台的强大功能来创建高度定制化的桌面应用程序。通过RCP,开发者能够专注于业务逻辑而非繁琐的界面设计,极大地提高了...
RCP应用通常拥有和Eclipse类似的外观与操作体验,例如动态的菜单栏(Menubar)、工具栏(Toolbar)、编辑器(Editor)、视图(View)、工作台窗口(WorkbenchWindow)以及工作区(WorkSpace)等。这些组件共同构成了...
6. **国际化和本地化**:Eclipse RCP支持多语言环境,开发者需要了解如何实现应用程序的国际化和本地化,包括资源文件的处理和语言切换机制。 7. **源代码实践**:压缩包中的源代码提供了实际的开发示例,通过分析...
7. **学习资源**:这个项目对于想要学习Eclipse RCP开发的初学者来说是一个宝贵的实例,他们可以从源代码中学习如何结合Eclipse RCP和MP3处理技术。 综上所述,"eclipse RCP mp3工程"不仅是一个实用的音频处理应用...
eclipse RCP Plug-in开发自学教程 eclipse RCP(Rich Client Platform)是一种基于eclipse的插件式开发平台,允许开发者使用eclipse结构风格设计弹性的可扩展的应用程序。RCP插件式开发方式可以重用eclipse中的方法...
2. **工作台(Workbench)**:工作台是Eclipse RCP应用程序的中心,负责管理窗口、视图、编辑器等元素。开发者可以自定义工作台布局,例如添加新的视图或编辑器。 3. **视图(View)**:视图是用户界面中显示特定...
8. **模型-视图-控制器(MVC)**:Eclipse RCP遵循MVC设计模式,模型负责数据管理,视图负责显示,控制器处理用户输入和模型-视图间的交互。 9. **透视图(Perspective)**:透视图是工作台的一种布局,可以包含多...
通过使用Eclipse RCP,开发者可以创建高度可定制和扩展的应用程序,这些应用不仅具有强大的功能,而且还能与其他Eclipse插件无缝集成。 ##### Eclipse Workbench Eclipse Workbench 是 Eclipse RCP 的核心组成部分...
本文将深入探讨如何利用Eclipse RCP进行编辑器开发,结合提供的描述,我们将分享一个初学者在学习RCP后完成的小程序案例。 首先,我们需要了解Eclipse RCP的核心概念。RCP是Eclipse IDE的底层架构,它提供了构建可...
Eclipse RCP(Rich Client Platform)是一个开源框架,用于构建功能丰富的桌面应用程序。它提供了丰富的用户界面组件和灵活的插件架构,使得开发者能够轻松创建复杂的软件应用。在这个"属性编辑器实例"中,我们将...
这个语言包包含了Eclipse RCP 3.6.0版本中的所有关键组件和功能的中文本地化资源。 3. **如何使用中文语言包** 要在Eclipse RCP项目中使用这个语言包,首先需要将其导入到Eclipse环境中。然后,在项目的插件配置中...
Eclipse RCP允许开发者创建功能丰富的、可扩展的应用程序,这些应用程序拥有与Eclipse集成开发环境相同级别的质量和用户体验。在"**Eclipse RCP开发详解**"中,我们将深入探讨这个主题,帮助你快速掌握Eclipse RCP...
Eclipse RCP是Eclipse IDE的一部分,它提供了一个框架,使得开发者可以构建功能丰富的、可定制的桌面应用程序。以下是对该书可能涉及的知识点的详细阐述: 1. **Eclipse RCP基础**:首先,书中会介绍Eclipse RCP的...
1. **Eclipse RCP基础**:首先,文章可能会介绍Eclipse RCP的基本概念,包括它的设计理念、架构和主要组件,如工作台(Workbench)、视图(Views)、编辑器(Editors)和透视图(Perspectives)。 2. **插件系统**...
1. **Navigator Model**:这是Common Navigator的核心,负责管理资源的层次结构。你可以通过实现`INavigatorModel`接口来定制自己的模型,或者使用默认的`WorkbenchNavigatorModel`。 2. **Navigator Content ...
### Eclipse RCP 详细教程 #### 1. 富客户端平台 ##### 1.1. 概述 Eclipse RCP(Rich Client Platform)是一种基于Java的框架,它允许开发者构建高度可定制和可扩展的桌面应用。这些应用通常具有丰富的用户界面,...