zoukankan      html  css  js  c++  java
  • 自定义SWT控件七之自定义Shell(可伸缩窗口)

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

  • 相关阅读:
    UIButton的遍历
    UIbutton 圆角和边线
    UIbutton 和UIview 切单角
    为运行Microsoft Dynamics CRM 异步处理服务指定账户没有性能计数器权限
    转:细说ASP.NET Windows身份认证
    CRM 模拟用户
    CRM 2016 Get IOrganizationService
    模拟SQL用户 EXECUTE AS USER
    Calling Custom Actions from JavaScript
    processjs Documentation
  • 原文地址:https://www.cnblogs.com/sandyflower/p/9750190.html
Copyright © 2011-2022 走看看