7、可伸缩窗口

该自定义窗口可以通过鼠标随意更改窗口大小

package com.hikvision.encapsulate.view.control.shell;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.events.ShellListener;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell; import com.hikvision.encapsulate.view.swt.SWTResourceManager; /**
* <p>自定义shell,该shell仅适用于无标题,即 style == SWT.NO_TRIM使用,提供放大缩小功能</p>
* @author wangfang5 2018年6月11日 下午2:32:07
* @version V1.0
*/
public class DefinedShell extends Shell {
private Point lastPos;
private boolean drag = false;
/**
* <p>锚点对象</p>
* @author wangfang5 2018年6月11日 下午1:39:43
* @version V1.0
*/
private class Anchor {
/**
* 锚点的光标对象
*/
final Cursor cusor;
/**
* 锚点位置计算的掩码
*/
final Rectangle mask;
Anchor(Cursor cusor, Rectangle mask) {
this.cusor = cusor;
this.mask=mask;
}
}
private int anchorIndex; // 光标定义
private final Cursor CURSOR_SIZENESW=new Cursor(Display.getDefault(),SWT.CURSOR_SIZENESW);
private final Cursor CURSOR_SIZENS=new Cursor(Display.getDefault(),SWT.CURSOR_SIZENS);
private final Cursor CURSOR_SIZENWSE=new Cursor(Display.getDefault(),SWT.CURSOR_SIZENWSE);
private final Cursor CURSOR_SIZEWE=new Cursor(Display.getDefault(),SWT.CURSOR_SIZEWE);
private final Cursor CURSOR_SIZEALL=new Cursor(Display.getDefault(),SWT.CURSOR_SIZEALL);
//lt+-------+-------+rt
// | t |
// | |
// | c |
//l + + +r
// | |
// | |
// | b |
//lb+-------+-------+rb
enum AnchorType{
LT,T,RT,L,C,R,LB,B,RB
} /**
* 9个锚点位置({@link Anchor})对象数组(按从左到右从上到下顺序排序)
*/
private final Anchor[] anchors=new Anchor[]{
new Anchor(CURSOR_SIZENWSE,new Rectangle(1,1,-1,-1)),
new Anchor(CURSOR_SIZENS,new Rectangle(0,1,0,-1)),
new Anchor(CURSOR_SIZENESW,new Rectangle(0,1,1,-1)),
new Anchor(CURSOR_SIZEWE,new Rectangle(1,0,-1,0)),
new Anchor(CURSOR_SIZEALL,new Rectangle(1,1,0,0)),
new Anchor(CURSOR_SIZEWE,new Rectangle(0,0,1,0)),
new Anchor(CURSOR_SIZENESW,new Rectangle(1,0,-1,1)),
new Anchor(CURSOR_SIZENS,new Rectangle(0,0,0,1)),
new Anchor(CURSOR_SIZENWSE,new Rectangle(0,0,1,1))};; public DefinedShell(int style){
super(style);
final Cursor defCursor=getCursor();
this.setBackground(SWTResourceManager.getWhiteColor());
if((style & SWT.NO_TRIM) != 0){
getDisplay().addFilter(SWT.MouseDown,event->{
try{
moveAbove(null);
Control control = (Control)event.widget;
if(control.getData("close") == null){
if(event.button == 1 && anchorIndex>=0){
drag = true;
lastPos = ((Control)(event.widget)).toDisplay(event.x, event.y);
}
}
}catch(Throwable e){
}
});
getDisplay().addFilter(SWT.MouseUp, event->{
drag = false;
});
addShellListener(new ShellListener() { @Override
public void shellIconified(ShellEvent e) {
// TODO Auto-generated method stub } @Override
public void shellDeiconified(ShellEvent e) {
// TODO Auto-generated method stub } @Override
public void shellDeactivated(ShellEvent e) {
drag = false;
} @Override
public void shellClosed(ShellEvent e) {
// TODO Auto-generated method stub } @Override
public void shellActivated(ShellEvent e) {
// TODO Auto-generated method stub }
});
getDisplay().addFilter(SWT.MouseMove, event->{
try{
if(drag){ //允许拖拽
Point pos=((Control)(event.widget)).toDisplay(event.x, event.y);
modify(pos.x-lastPos.x,pos.y-lastPos.y,anchors[anchorIndex].mask);
lastPos = pos;
}else{
//查找相对于shell的坐标
Point point = getRelativeShellPoint((Control)event.widget,event.x ,event.y);
anchorIndex = getAnchorIndex(point.x ,point.y);
if(anchorIndex == -1){ //未选中可以拖拽的边
setCursor(defCursor);
}else{
setCursor(anchors[anchorIndex].cusor);
}
}
}catch(Throwable e){
}
});
}
} /**
* 获取相对于shell的坐标
* @author wangfang5 2018年6月11日 下午5:14:34
* @param control
* @return
*/
private Point getRelativeShellPoint(Control control,int eventX,int eventY){
int x = eventX;
int y = eventY;
Control now = control;
while(!(now instanceof Shell)){
x += now.getBounds().x;
y += now.getBounds().y;
now = now.getParent();
}
return new Point(x,y);
} @Override
protected void checkSubclass(){
}
/**
* 改变窗口位置和尺寸
* @param x x轴移动距离
* @param y y轴移动距离
* @param mask 锚点位置计算的掩码
*/
private void modify(int x,int y,Rectangle mask){
// 计算出新的窗口位置和尺寸
Rectangle bound = getBounds();
bound.x+=x*mask.x;
bound.y+=y*mask.y;
bound.width+=x*mask.width;
bound.height+=y*mask.height;
// 设置新的窗口位置
setBounds(bound);
redraw();
} /**
* 获取锚点
* @author wangfang5 2018年6月11日 下午2:00:57
* @param mousex
* @param mousey
* @return
*/
private int getAnchorIndex(int mousex,int mousey){
try{
Rectangle bound = getBounds();
if(Math.abs(mousex - bound.width) < 10 && mousey < 10){ //右上角、
return AnchorType.RT.ordinal();
}else if(Math.abs(mousey - bound.height) <= 10 && mousex < 10){ //左下角
return AnchorType.LB.ordinal();
}if(0 <= mousey && mousey < 10 && 0 <= mousex && mousex < 10){ //左上角
return AnchorType.LT.ordinal();
}else if(Math.abs(mousey - bound.height) <= 10 && Math.abs(mousex - bound.width) < 10){ //右下角
return AnchorType.RB.ordinal();
}else if (0 <= mousey && mousey < 5) { //上、
return AnchorType.T.ordinal();
} else if(Math.abs(mousey - bound.height) <= 5){ //下
return AnchorType.B.ordinal();
}else if (0 <= mousex && mousex< 5) { //左
return AnchorType.L.ordinal();
}else if(Math.abs(mousex - bound.width) <= 5){ //右
return AnchorType.R.ordinal();
}else
return -1;
}catch(Throwable e){
return -1;
}
} @Override
public void open() {
// TODO Auto-generated method stub
super.open();
drag = false;
}
}
使用范例:

public MainUI() {
Display display = Display.getDefault();
shell = new DefinedShell(SWT.NO_TRIM | SWT.NONE);
shell.setMinimumSize(shellMinWidth, shellMinHeight);
shell.setBackground(SWTResourceManager.getColor(51, 51, 51));
int shellWidth = 1280;
int shellHeight = 800;
shell.setMaximized(true);
shell.setMinimized(true);
int x = Display.getCurrent().getClientArea().width/2 - shellWidth / 2;
int y = Display.getCurrent().getClientArea().height / 2 - shellHeight / 2;
if(x <= 0){
x = 0;
shellWidth = Display.getCurrent().getClientArea().width/2;
if(shellWidth < (shellMinWidth + 100)){
shellWidth = shellMinWidth + 100;
}
}
if(y<=0){
y = 0;
shellHeight = Display.getCurrent().getClientArea().height/2;
if(shellHeight < (shellMinHeight+100)){
shellHeight = shellMinHeight+100;
}
if((shellHeight + 400)<shellWidth){
shellWidth = shellHeight + 400;
}
}
shell.setLocation( Display.getCurrent().getClientArea().width/ 2 - shellWidth / 2,
Display.getCurrent().getClientArea().height / 2 - shellHeight / 2);
shell.setSize(shellWidth, shellHeight);
} //若是需要最大化按钮和最小化按钮(自己提供的图标),需要给他们绑上事件,代码如下:
Label min_label = new Label(tool_bar_composite, SWT.NONE);
  min_label.setBackground(SWTResourceManager.getColor(51, 51, 51));
  min_label.setForeground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
  GridData gd_min_label = new GridData(SWT.RIGHT,SWT.CENTER,true,false,1,1);
  gd_min_label.heightHint = 24;
  gd_min_label.widthHint = 24;
  min_label.setLayoutData(gd_min_label);
  min_label.setImage(ImageUtil.getImage(FileUtil.loadResourceFileAsStream(Constants.MININIZE)));
  min_label.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_HAND));
  min_label.setToolTipText("最小化");
  min_label.addListener(SWT.MouseDown, event ->{
   shell.setMinimized(true);
  });
  
  Label max_label = new Label(tool_bar_composite, SWT.NONE);
  max_label.setBackground(SWTResourceManager.getColor(51, 51, 51));
  max_label.setForeground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
  GridData gd_max_label = new GridData(SWT.RIGHT,SWT.CENTER,true,false,1,1);
  gd_max_label.heightHint = 24;
  gd_max_label.widthHint = 24;
  max_label.setLayoutData(gd_max_label);
  max_label.setImage(ImageUtil.getImage(FileUtil.loadResourceFileAsStream(Constants.MAXIMIZE)));
  max_label.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_HAND));
  max_label.setToolTipText("最大化");
  max_label.addListener(SWT.MouseDown, event ->{
   if(shell.getFullScreen()){
    shell.setFullScreen(false);
    max_label.setImage(ImageUtil.getImage(FileUtil.loadResourceFileAsStream(Constants.MAXIMIZE)));
    max_label.setToolTipText("最大化");
   }else{
    shell.setFullScreen(true);
    max_label.setImage(ImageUtil.getImage(FileUtil.loadResourceFileAsStream(Constants.RESTORE)));
    max_label.setToolTipText("恢复");
   }
  });

以上DefinedShell提供了通过鼠标改变窗口大小功能,范例中提供了放大窗口和缩小窗口功能。

自定义SWT控件七之自定义Shell(可伸缩窗口)的更多相关文章

  1. 自定义SWT控件六之自定义Tab

    6.自定义tab 本章节提供的自定义tab 分为两类 tab上带删除按钮和添加按钮,可删除tab和添加tab tab不可删除和添加 6.1 不可删除tab package com.view.contr ...

  2. 自定义SWT控件二之自定义多选下拉框

    2.自定义下拉多选框 package com.view.control.select; import java.util.ArrayList; import java.util.HashMap; im ...

  3. 自定义SWT控件一之自定义单选下拉框

    一.自定义下拉控件 自定义的下拉框,是自定义样式的,其中的下拉框使用的是独立的window,非复选框的下拉框双击单机其它区域或选择完之后,独立window构成的下拉框会自动消失. package co ...

  4. 自定义SWT控件五之自定义穿梭框

    5.自定义穿梭框 package com.view.control.shuttlebox; import java.util.ArrayList; import java.util.HashMap; ...

  5. 自定义SWT控件四之其它下拉框

    4.其它下拉框 4.1 添加联动二级多选择框(有添加按钮和删除按钮) package com.view.control.select; import java.util.ArrayList; impo ...

  6. IOS开发--自定义segment控件,方便自定义样式

    系统的segment控件太封闭,想换个颜色加个背景太难了,忍不住自己写一个,以备不时之需 这个控件给出了很多自定义属性的设置,用起来还是比较方便的,需要注意的 itemWidth如果不设置,则会按照控 ...

  7. 自定义SWT控件三之搜索功能下拉框

    3.搜索功能下拉弹出框 package com.view.control.select; import java.util.ArrayList; import java.util.LinkedList ...

  8. javascript实例学习之六—自定义日历控件

    基于之前上篇博客轻量级jquery,tool.js和base.js.自定义开发的base_datePicker插件,效果类似于jquery_ui的datePicker插件 //基于Base.js以及t ...

  9. 【转】带checkbox的ListView实现(二)——自定义Checkable控件的实现方法

    原文网址:http://blog.csdn.net/harvic880925/article/details/40475367 前言:前一篇文章给大家展示了传统的Listview的写法,但有的时候我们 ...

随机推荐

  1. 【设计模式】结构型02装饰模式(Decorator Pattern)

    装饰模式(Decorator Pattern) 意图:动态地给一个对象添加一些额外的职责.就增加功能来说,装饰器模式相比生成子类更为灵活. 主要解决:一般的,我们为了扩展一个类经常使用继承方式实现,由 ...

  2. Jenkins+Python+GitLab持续集成

    创建任务 登录Jenkins,点击左侧列表的新建选项.输入任务名称,选择构建一个自由风格的软件项目,点击确定. 配置 在任务配置界面,可以设置General标签中的丢弃旧的构建选项,设置保持构建的天数 ...

  3. 跟着大彬读源码 - Redis 1 - 启动服务,程序都干了什么?

    一直很羡慕那些能读 Redis 源码的童鞋,也一直想自己解读一遍,但迫于 C 大魔王的压力,解读日期遥遥无期. 相信很多小伙伴应该也都对或曾对源码感兴趣,但一来觉得自己不会 C 语言,二来也不知从何入 ...

  4. 微信小程序源码

    内带scroll滚动轮播:如图:       微信小程序开发工具:微信开发工具: 文件目录: images:小程序的图标 pages:小程序页面 utils:方法js git地址:https://gi ...

  5. 环形缓存RingBuf的几种实现方式(数组,链表),及Disruptor的分析

    先贴个头文件的设计: 首先缓冲区中没有任何数据时,nIdWrite.nIdRead读写下标都为0. 为了判断缓冲区中是否还有数据可读或者可写,我判断的依据是:1)当nIdWrite 等于 nIdRea ...

  6. oracle获取当天时间的最开始的时间和最结尾的时间

    ),,'yyyy-mm-dd')||' 23:59:59' from dual

  7. 提升布局性能____Making ListView Scrolling Smooth

    listview是一个比较重要的UI组件,一切影响UI的操作,比如适配器从磁盘.网络或者数据库中加载数据的操作,最好都放在子线程中完成.子线程可以使用thread,不过那样比较老土,官方推荐使用Asy ...

  8. Ray聊天记录

    由于工作变动,Ray的文档.示例没有及时更新,深表歉意.在Ray升级后,性能较几个月前有了非常大的提升,也更具易用性.这是QQ交流群里大家的聊天记录,跟大家分享一下(由于时间仓促群里大家的聊天记录没有 ...

  9. 【拓扑排序】威虎山上的分配-C++

    威虎山上的分配 描述 每年过年的时候,座山雕都会给兄弟们分银子,分银子之前,座山雕允许大伙儿发表意见,因为要是没法满足所有人的意见,指不定谁要搞出什么大新闻.不过每个人在提意见的时候只能说:" ...

  10. ViewPager取消切换动画

    /** * Created by apk2sf on 2017/12/2. * email: apk2sf@163.com * QQ:337081267 */ public class NoAnima ...