博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
自定义SWT控件七之自定义Shell(可伸缩窗口)
阅读量:5142 次
发布时间:2019-06-13

本文共 9857 字,大约阅读时间需要 32 分钟。

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;/** * 

自定义shell,该shell仅适用于无标题,即 style == SWT.NO_TRIM使用,提供放大缩小功能

* @author wangfang5 2018年6月11日 下午2:32:07 * @version V1.0 */public class DefinedShell extends Shell { private Point lastPos; private boolean drag = false; /** *

锚点对象

* @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)
{
   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提供了通过鼠标改变窗口大小功能,范例中提供了放大窗口和缩小窗口功能。

转载于:https://www.cnblogs.com/sandyflower/p/9750190.html

你可能感兴趣的文章
Swift 入门之简单语法(六)
查看>>
jquery validate name相同通过id验证
查看>>
CentOS下安装MySQL
查看>>
iOS 沙盒目录结构介绍
查看>>
os.popen()
查看>>
RedHat7搭建yum源服务器
查看>>
react propTypes验证规则
查看>>
jquery.validate使用【转】
查看>>
Tour HDU - 3488
查看>>
java反射详解zz
查看>>
mysql 导出表结构和表数据 mysqldump用法
查看>>
Ubuntu下忘记MySQL密码重设方法
查看>>
+new Date()的用法
查看>>
Git 使用
查看>>
JavaScript 语句 while
查看>>
Function eregi() is deprecated (解决方法)
查看>>
win7 iis7 HTTP 错误 401.3 - Unauthorized
查看>>
Oracle注意事项
查看>>
容器(docker)内运行Nginx
查看>>
WinCE应用程序开发---打开或另存为对话框
查看>>