java SWT入门:自定义背景透明且可鼠标拖动改变尺寸和位置的Composite

本文主要是介绍java SWT入门:自定义背景透明且可鼠标拖动改变尺寸和位置的Composite,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

下面的代码实现了一个透明可移动可改变尺寸的Composite窗体,如下图
这里写图片描述
鼠标点击窗口获取焦点,在获取焦点时会显示9个锚点用于改变窗口的位置和尺寸。
可以通过鼠标拖动锚点来改变窗口的位置或尺寸,也可以通过上下左右键来移动窗口

ActiveRectangle.java

package net.gdface.ui;import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.wb.swt.SWTResourceManager;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;/*** 自定义透明窗口,* 窗口位置和尺寸可以通过鼠标和上下左右键修改* @author gudong*/
public class ActiveRectangle extends Composite {/*** 锚点对象* @author guyadong*/private class Anchor {/*** 描述锚点位置尺寸的矩形对象*/final Rectangle rect=new Rectangle(0, 0, anchorSize, anchorSize);/*** 锚点的光标对象*/final Cursor cusor;/*** 锚点位置计算的掩码*/final Rectangle mask;Anchor(Cursor cusor, Rectangle mask) {this.cusor = cusor;this.mask=mask;}}/*** 焦点矩形边框颜色*/private static Color focusRectColor=SWTResourceManager.getColor(SWT.COLOR_GREEN);/*** 非焦点矩形边框颜色*/private static Color nofocusRectColor=SWTResourceManager.getColor(SWT.COLOR_RED);/*** 矩形边框线宽*/private static int lineWidth=1; /*** 锚点矩形尺寸*/private static int anchorSize=8;/*** 上下左右键移动窗口的步长*/private static int arrowStep=1;/*** 是否焦点*/boolean focus=true;/*** 当前鼠标位置所在的锚点索引 {@link #anchors} */private int anchorIndex=-1;// 光标定义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+-------+-------+rbenum 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))};;   /*** 矩形修改标记,为true时,处于鼠标拖动修改窗口位置和尺寸的状态,* 鼠标位于9个锚点区域({@link Anchor})之一,且鼠标键按下(mouseDown)*/private boolean onMouseModfied;/*** 矩形修改状态下({@link #onMouseModfied}为true),记录上次鼠标位置*/private Point lastPos;/*** 真实的窗口位置和尺寸*/protected Rectangle originalBounds;private boolean originalBoundsNeedupdate=false;/*** 父窗口x轴缩放比例*/private float zoomY;/*** 父窗口y轴缩放比例*/private float zoomX;/*** Create the composite.* @param parent* @param isFocus 是否为焦点对象* @param originalBounds 对象原始位置尺寸*/public ActiveRectangle(Composite parent, boolean isFocus, Rectangle originalBounds) {// 透明背景样式super(parent, SWT.TRANSPARENT);this.originalBounds = originalBounds;this.focus=isFocus;     addPaintListener(new PaintListener() {public void paintControl(PaintEvent e) {// 绘制透明矩形窗口e.gc.setLineStyle(SWT.LINE_SOLID);e.gc.setLineWidth(lineWidth);e.gc.setForeground(focus?focusRectColor:nofocusRectColor);Point size = getSize();             e.gc.drawRectangle(new Rectangle(0,0,--size.x,--size.y));if(focus){Color bc = e.gc.getBackground();                    e.gc.setBackground(focusRectColor);e.gc.fillRectangle(anchors[AnchorType.LT.ordinal()].rect.x, anchors[AnchorType.LT.ordinal()].rect.y, anchorSize, anchorSize);e.gc.fillRectangle(anchors[AnchorType.T.ordinal()].rect.x, anchors[AnchorType.T.ordinal()].rect.y, anchorSize, anchorSize);e.gc.fillRectangle(anchors[AnchorType.RT.ordinal()].rect.x, anchors[AnchorType.RT.ordinal()].rect.y, anchorSize, anchorSize);                   e.gc.fillRectangle(anchors[AnchorType.L.ordinal()].rect.x, anchors[AnchorType.L.ordinal()].rect.y, anchorSize, anchorSize);// 画中心十字e.gc.drawLine(anchors[AnchorType.C.ordinal()].rect.x+(anchorSize>>1), anchors[AnchorType.C.ordinal()].rect.y, anchors[AnchorType.C.ordinal()].rect.x+(anchorSize>>1), anchors[AnchorType.C.ordinal()].rect.y+anchorSize);e.gc.drawLine(anchors[AnchorType.C.ordinal()].rect.x, anchors[AnchorType.C.ordinal()].rect.y+(anchorSize>>1), anchors[AnchorType.C.ordinal()].rect.x+anchorSize, anchors[AnchorType.C.ordinal()].rect.y+(anchorSize>>1));e.gc.fillRectangle(anchors[AnchorType.R.ordinal()].rect.x, anchors[AnchorType.R.ordinal()].rect.y, anchorSize, anchorSize);e.gc.fillRectangle(anchors[AnchorType.LB.ordinal()].rect.x, anchors[AnchorType.LB.ordinal()].rect.y, anchorSize, anchorSize);e.gc.fillRectangle(anchors[AnchorType.B.ordinal()].rect.x, anchors[AnchorType.B.ordinal()].rect.y, anchorSize, anchorSize);e.gc.fillRectangle(anchors[AnchorType.RB.ordinal()].rect.x, anchors[AnchorType.RB.ordinal()].rect.y, anchorSize, anchorSize);                   // 恢复背景色e.gc.setBackground(bc);                 }}});// 当获取/失去焦点时重绘窗口addFocusListener(new FocusAdapter() {@Overridepublic void focusGained(FocusEvent e) {focus=true;// 将对象设置到顶层,否则无法响应所有的mouseMove事件moveAbove(null);((Control)(e.widget)).redraw();}@Overridepublic void focusLost(FocusEvent e) {focus=false;((Control)(e.widget)).redraw();}});// 实现上下左右键移动窗口addKeyListener(new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {switch(e.keyCode){case SWT.ARROW_LEFT:modify(-arrowStep,0,anchors[AnchorType.C.ordinal()].mask);break;case SWT.ARROW_RIGHT:modify(arrowStep,0,anchors[AnchorType.C.ordinal()].mask);break;case SWT.ARROW_UP:modify(0,-arrowStep,anchors[AnchorType.C.ordinal()].mask);break;case SWT.ARROW_DOWN:modify(0,arrowStep,anchors[AnchorType.C.ordinal()].mask);break;default:}}});// 加入mouseMove事件处理,实现鼠标拖动锚点改变窗口位置和尺寸addMouseMoveListener(new MouseMoveListener() {private final Cursor defCursor=getCursor();         public void mouseMove(MouseEvent e) {if(focus){if(onMouseModfied){// 计算鼠标移动的距离Point pos=((Control)(e.widget)).toDisplay(e.x, e.y);modify(pos.x-lastPos.x,pos.y-lastPos.y,anchors[anchorIndex].mask);// 记录当前鼠标位置,以供下次mouseMove消息时计算鼠标移动距离lastPos=pos;}else   if((anchorIndex=anchored(e.x, e.y))>=0&&anchors[anchorIndex].cusor!=getCursor()){// 当鼠标位置某个锚点时,更新鼠标形状setCursor(anchors[anchorIndex].cusor);}else   if(defCursor!=getCursor())// 鼠标不在锚点时,恢复默认鼠标形状setCursor(defCursor);}else anchorIndex=-1;}});// 配合MouseMoveListener实现鼠标改变窗口位置和尺寸addMouseListener(new MouseAdapter() {           @Overridepublic void mouseDown(MouseEvent e) {if(anchorIndex>=0){// 记录当前鼠标位置,以供mouseMove消息时计算鼠标移动距离lastPos=((Control)(e.widget)).toDisplay(e.x, e.y);onMouseModfied=true;}else if(!isFocusControl()){// 当前对象非焦点对象时,设置当前对象为焦点对象setFocus();}}@Overridepublic void mouseUp(MouseEvent e) {onMouseModfied=false;}});}@Overrideprotected void checkSubclass() {// Disable the check that prevents subclassing of SWT components}/*** 改变窗口位置和尺寸* @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;// 设置新的窗口位置this.originalBoundsNeedupdate=true;setBounds(bound);this.originalBoundsNeedupdate=false;}@Overridepublic void dispose() {// 释放光标资源CURSOR_SIZENESW.dispose();CURSOR_SIZENS.dispose();CURSOR_SIZENWSE.dispose();CURSOR_SIZEWE.dispose();CURSOR_SIZEALL.dispose();super.dispose();}/*** 根据窗口尺寸计算各个{@link Anchor}的位置*/private void setAnchors(){Point size = getSize();setAnchorPos(anchors[AnchorType.LT.ordinal()].rect,0, 0);setAnchorPos(anchors[AnchorType.T.ordinal()].rect,(size.x-anchorSize)>>1, 0);setAnchorPos(anchors[AnchorType.RT.ordinal()].rect,size.x-anchorSize, 0);setAnchorPos(anchors[AnchorType.L.ordinal()].rect,0, (size.y-anchorSize)>>1);setAnchorPos(anchors[AnchorType.C.ordinal()].rect,(size.x-anchorSize)>>1, (size.y-anchorSize)>>1);setAnchorPos(anchors[AnchorType.R.ordinal()].rect,size.x-anchorSize, (size.y-anchorSize)>>1);setAnchorPos(anchors[AnchorType.LB.ordinal()].rect,0, size.y-anchorSize);setAnchorPos(anchors[AnchorType.B.ordinal()].rect,(size.x-anchorSize)>>1, size.y-anchorSize);setAnchorPos(anchors[AnchorType.RB.ordinal()].rect,size.x-anchorSize, size.y-anchorSize);}private void setAnchorPos(Rectangle anchorRect,int x,int y){anchorRect.x=x;anchorRect.y=y;}/*** 计算指定的坐标(x,y)是否位于某个{@link Anchor}区域* @param x* @param y* @return 返回 {@link #anchors}的索引值,不在任何一个{@link Anchor}则返回-1*/private int anchored(int x,int y){for(int i=0;i<anchors.length;++i){if(anchors[i].rect.contains(x, y))return i;}return -1;}private void setOriginalBounds(Rectangle rect){// 如果originalBounds没有初始化,则用第一次调用setBounds的参数来初始化if(null==originalBounds)originalBounds=rect;else if(originalBoundsNeedupdate)// 非zoom状态下更新将当前窗口的尺寸换算后更新originalBoundsoriginalBounds=unZoom(zoomX,zoomY);}@Overridepublic void setBounds(int x, int y, int width, int height) {super.setBounds(x, y, width, height);// 重写setBounds方法,修改窗口位置和尺寸时同步重新计算所有锚点位置setAnchors();setOriginalBounds(new Rectangle(x, y, width, height));}@Overridepublic void setBounds(Rectangle rect) {super.setBounds(rect);// 重写setBounds方法,修改窗口位置和尺寸时同步重新计算所有锚点位置setAnchors();setOriginalBounds(rect);}/*** 根据zoom缩放比例缩放矩形显示* @param zoomX x轴缩放比例* @param zoomY y轴缩放比例*/protected void zoom(float zoomX, float zoomY) {if(null!=originalBounds){this.zoomX=zoomX;this.zoomY=zoomY;setBounds(new Rectangle((int)(originalBounds.x*zoomX),(int)(originalBounds.y*zoomY),(int)(originalBounds.width*zoomX),(int)(originalBounds.height*zoomY)));}}/*** x,y轴等比例缩放* @param rect* @param zoom x,y轴缩放比例* @see #zoom(float, float)*/void zoom(Rectangle rect, float zoom) {     zoom(zoom,zoom);}/*** 根据zoom缩放比例返回缩放前的矩形对象({@link Rectangle})* @param zoomX x轴缩放比例* @param zoomY y轴缩放比例* @return*/protected Rectangle unZoom(float zoomX, float zoomY) {  Rectangle bounds = getBounds();return new Rectangle((int)(bounds.x/zoomX),(int)(bounds.y/zoomY),(int)(bounds.width/zoomX),(int)(bounds.height/zoomY));     }/*** x,y轴等比例缩放* @param zoom x,y轴缩放比例* @return* @see #unZoom(float, float)*/protected Rectangle unZoom(float zoom) {    return unZoom(zoom,zoom);       }}

测试代码
TestActiveRectangle.java

package testwb;import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;import net.gdface.ui.ActiveRectangle;import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Control;public class TestActiveRectangle extends Dialog {protected Object result;protected Shell shell;/*** Create the dialog.* @param parent* @param style*/public TestActiveRectangle(Shell parent, int style) {super(parent, style);setText("SWT Dialog");}/*** Open the dialog.* @return the result*/public Object open() {createContents();shell.open();shell.layout();Display display = getParent().getDisplay();while (!shell.isDisposed()) {if (!display.readAndDispatch()) {display.sleep();}}return result;}/*** Create contents of the dialog.*/private void createContents() {shell = new Shell(getParent(), getStyle());shell.setSize(463, 366);shell.setText(getText());Group group = new Group(shell, SWT.NONE);group.setBounds(10, 10, 423, 302);Composite composite2 = new ActiveRectangle(group, false, null);composite2.setBounds(81, 102, 51, 90);Composite composite1 = new ActiveRectangle(group, true, null);composite1.setBounds(24, 141, 147, 90);group.setTabList(new Control[]{composite2, composite1});shell.setTabList(new Control[]{group});}
}

这篇关于java SWT入门:自定义背景透明且可鼠标拖动改变尺寸和位置的Composite的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/837560

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听