关于Draw2D里的Layout

简介:

就像在swt里我们使用layout来控制各个控件的摆放位置一样,在Draw2D里最好也把这个工作交给LayoutManager来做。除非是在自己实现的Layout里,一般程序里自己不要轻易使用setBounds()、setLocation()和setSize()这些方法控制图形的位置和大小,而应该在为每个图形设置了适当的LayoutManager后,通过setConstraint()和setPreferredSize()等方法告诉layoutmanager如何布局。

在需要的时候,父图形的布局管理器负责修改每个子图形的位置和大小,但计算每个子图形大小的工作可能是交给子图形自己的LayoutManager来做的,计算的方法一般是在这个LayoutManager的getPreferredSize()方法里体现。

例如当父图形使用XYLayout,子图形使用ToolbarLayout时,假设在子图形里又增加了子子图形(子图形里的子图形),add()方法会导致revalidate()的调用,这时父图形的xylayout将检查子图形是否具有constraint,如果有并且有至少一个方向为-1,则利用子图形上的ToolbarLayout计算出子图形新的尺寸,这个尺寸是和子图形里包含的子子图形的数目有关的(ToolbarLayout会把每个子图形的宽/高度加起来,加上其中间隔的空间,再考虑图形的边框,返回得到的尺寸)。

XYLayout对layout(IFigure)方法的实现:

public   void  layout(IFigure parent) {
    Iterator children 
=  parent.getChildren().iterator();
    Point offset 
=  getOrigin(parent);
    IFigure f;
    
while  (children.hasNext()) {
        f 
=  (IFigure)children.next();
        Rectangle bounds 
=  (Rectangle)getConstraint(f); // 因此必须为子图形指定constraint
         if  (bounds  ==   null continue ;

        
if  (bounds.width  ==   - 1   ||  bounds.height  ==   - 1 ) {
            Dimension preferredSize 
=  f.getPreferredSize(bounds.width, bounds.height);
            bounds 
=  bounds.getCopy();
            
if  (bounds.width  ==   - 1 )
                bounds.width 
=  preferredSize.width;
            
if  (bounds.height  ==   - 1 )
                bounds.height 
=  preferredSize.height;
        }
        bounds 
=  bounds.getTranslated(offset);
        f.setBounds(bounds);
    }
}

Draw2D里Figure类的setPreferredSize(Dimension)和setSize(Dimension)的区别是,setSize()方法不会调用revalidate()方法导致重新layout,而只是调用repaint()对所涉及到的“脏”区域进行重绘(repaint)。setPreferredSize()方法可以约等于setSize()方法+revalidate()方法,因为在Figure对getPreferredSize(int,int)的实现里,若该figure没有任何layoutmanager,则返回当前size:

public  Dimension getPreferredSize( int  wHint,  int  hHint) {
    
if  (prefSize  !=   null )
        
return  prefSize;
    
if  (getLayoutManager()  !=   null ) {
        Dimension d 
=  getLayoutManager().getPreferredSize( this , wHint, hHint);
        
if  (d  !=   null )
            
return  d;
    }
    
return  getSize();
}
 

只要看一下ToolbarLayout.java就会知道,ToolbarLayout对constraint是不感兴趣的,调用它的getConstraint()永远返回null值,所以我们不必对放在使用ToolbarLayout的图形的子图形设置constraint。因此,假如我们的问题是,有图形A包含B,B包含C,要实现B(使用ToolbarLayout)尺寸随C数目多少而自动改变该如何做呢?这要看A使用何种LayoutManager,如果是ToolbarLayout则不用做特殊的设置,如果是XYLayout则要用A.getLayoutManager().setConstraint(B,new Rectangle(x,y,-1,-1))这样的语句为A设置constraint,对图形C则用setPreferredSize()指定实际大小。

一个Layout的例子,点此下载,截图如下。

本文转自博客园八进制的博客,原文链接:关于Draw2D里的Layout,如需转载请自行联系原博主。

相关文章
|
存储 对象存储 UED
CDN适用哪些场景?
CDN是将源站内容分发至最接近用户的节点,使用户可就近取得所需内容,提高用户访问的响应速度和成功率。今天为大家分享几个CDN的典型适用场景。
16594 0
|
XML 缓存 API
Android 7.0之访问文件的权限和FileProvider类
转载请标明出处: http://blog.csdn.net/djy1992/article/details/72533310 本文出自:【奥特曼超人的博客】 权限更改 Android 7.0 做了一些权限更改,这些更改可能会影响您的应用。
3957 0
|
Web App开发 JavaScript
Chrome Console 中的 '$' 和Console Importer
Chrome Console 中的 '$' 和Console Importer
179 0
|
Java 应用服务中间件 开发工具
功能开关最佳实践
功能开关是一个轻量级的动态配置框架,通过功能开关可以动态管理代码中的配置项,根据需求为某个应用开启或关闭部分功能,或设置某个性能指标的阈值。功能开关通常用于设置黑白名单、运行时动态调整日志级别、降级业务功能等场景。本文介绍最佳实践。
608 1
阿里云域名代续费及域名查找阿里云账号的方法
域名续费只有原注册人可以续费吗?阿里云域名支持代续费功能,通过域名也可以查找忘记的阿里云账号
1549 0
阿里云域名代续费及域名查找阿里云账号的方法
|
Windows
阿里云ACA适合什么人考?通过是不是很简单?
阿里云认证是现在很热门的一个人才认证,不管是专业人士、还是想转行的没基础的人,都会选择考这个认证,其中的ACA认证是很多人都会考的。
558 0
阿里云ACA适合什么人考?通过是不是很简单?
|
Prometheus 监控 Cloud Native
SpringBoot服务监控机制,总算整明白了!
SpringBoot服务监控机制,总算整明白了!
SpringBoot服务监控机制,总算整明白了!
|
机器学习/深度学习 新零售 人工智能
RPA百年发展简史:RPA的史前背景、发展历程与四阶进化
RPA百年简史:从第一条自动化生产线到RPA成为流程自动化首选方案 RPA百年发展简史:RPA的史前背景、发展历程与四阶进化 RPA百年简史:90年自动化与信息技术更迭,15载成就RPA如今声名
1889 1
RPA百年发展简史:RPA的史前背景、发展历程与四阶进化
|
Linux Windows 容器
7.10 Linux yum源及配置
前面分别介绍了使用 SRPM 源码包和 RPM 二进制包安装软件,这两种方法都比较繁琐,需要手动解决包之间具有依赖性的问题,尤其是库文件依赖,需要自行去 http://www.rpmfind.net 网站上查找相关的 RPM 包。本节介绍一种可自动安装软件包(自动解决包之间依赖关系)的安装方式。
637 0
7.10 Linux yum源及配置
|
SQL 存储 分布式计算
Apache Hudi重磅特性解读之存量表高效迁移机制
随着Apache Hudi变得越来越流行,一个挑战就是用户如何将存量的历史表迁移到Apache Hudi,Apache Hudi维护了记录级别的元数据以便提供upserts和增量拉取的核心能力。为利用Hudi的upsert和增量拉取能力,用户需要重写整个数据集让其成为Hudi表。此RFC提供一个无需重写整张表的高效迁移机制。
694 0
Apache Hudi重磅特性解读之存量表高效迁移机制