`

SWT shell实现漫游窗

    博客分类:
  • swt
阅读更多

如何在eclipse中视图或某些编辑区域内实现漫游窗?如同Microsoft words样式窗口。更进一步的要求是漫游窗只能在窗口编辑区域内游动。

 

首先能想到的是使用一个shell,如果一个shell通过代码控制,使其location只能在编辑区内,剩下的旧好办。如此,就要使用非模态shelldialog了,在SWT中靠SWT.MODELESS表明。

背景知识:

Shell模式:http://blog.csdn.net/g5dsk/article/details/4350307

所谓"模式"窗口, 就是指除非采取有效的关闭手段, 用户的鼠标焦点或者输入光标将一直停留在其上的窗口. 非模态窗口则不会强制此种特性, 用户可以在当前窗口以及其他窗口间进行切换.

Shell组件包含一个称做"模式"的样式, 该样式用于决定是否阻拦该Shell组件依赖的display上的其他输入. 该样式可以是SWT.APPLICATION_MODAL, SWT.MODELESS, SWT.PRIMARY_MODALSWT.SYSTEM_MODAL. SWT.PRIMARY_MODAL样式允许Shell组件阻拦对其父组件的输入; SWT.APPLICATION_MODAL样式阻拦Shell组件依赖的display上的所有其他Shell组件的输入; 样式SYSTEM_MODAL样式阻拦当前系统中所有的向Shell组件的输入.

不同的平台对阻拦"模式"的支持有所不同. 在这种情况下, SWT会进行相应的"向上向下兼容". 比如一些操作系统就不支持SYSTEM_MODAL, 此时就会向下兼容, 使用APPLICATION_MODAL.

 

使用下面的代码创建了一个窗体。

Shell shell = new Shell(getShell(), SWT.MODELESS|SWT.TITLE |SWT.CLOSE);

shell.setSize(100, 100);

shell.open();

 

这个窗体有边框和title。不符合需要,需要将SWT.TITLE |SWT.CLOSE这两个style去掉,但在实现阶段,先留着,最后再去掉。

 

下面设置窗体location,先来看看窗体宽度,边框,标题等数据(在windows xp主题下)。

通过使用增加mouseMoveListener监听器方式,看代码:

publicvoid mouseMove(MouseEvent e)

 {

      System.out.println(shell.getLocation());// shell左定点位置

      System.out.println(shell.computeSize(SWT.DEFAULT, SWT.DEFAULT));

      System.out.println(shell.computeSize(SWT.DEFAULT, SWT.DEFAULT, false));

      System.out.println(e.x + ":" + e.y);// e.x,e.yshell面板左顶点为坐标0点开始算,不是从title的左顶点为0点计算

      System.out.println(shell.computeTrim(e.x, e.y, 100, 100));

      System.out.println(shell.getSize());// 宽度变成了123,高度还是设定的100

      System.out.println(shell.getClientArea());// 面板宽度是117,高度为68,因此标题高度为32

      System.out.println();

}

shell的标题栏左上角顶点与屏幕的左上角顶点重合。打印结果如下:

Point {0, 0}

Point {70, 96}

Point {70, 96}

1:0

Rectangle {-2, -29, 106, 132}

Point {123, 100}

Rectangle {0, 0, 117, 68}

解释:

Point {0, 0}-->>可知shell.getLocation()在有标题的情况下,得到的是左上顶点的位置

1:0-->>(鼠标从shellclient的左上角划过)可知,鼠标移动中产生的e.xe.y是相对shellclient左上角的。

 

shellsize设定为50,50.再次运行程序。结果如下:

Point {0, 0}

Point {70, 96}

Point {70, 96}

0:0

Rectangle {-3, -29, 106, 132}

Point {123, 50}

Rectangle {0, 0, 117, 18}

 

解释:

Point {123, 100}

Rectangle {0, 0, 117, 68}

Point {123, 50}

Rectangle {0, 0, 117, 18}

在有标题的情况下,shell.getClientArea()给出clientrect宽度是117,高度是68,再来比较一下设定两个不同shellsize。可知在标题有close叉的情况下,shell的宽度最小为123,其中包括边框宽度3.所以client的宽度就是123-6 = 117.而标题栏的高度是 100 – 68 – 3(边框宽) == 50 – 18 - 3(边框宽) == 29。我们可以通过shellsize设定为200,200.来验证shell边框的宽度和标题栏的高度。而给出的clientArea的顶点xy总是clientArea左上角对应于clientArea的位置(也即,总是0,0)。

 

解释:

Point {70, 96}

Point {70, 96}

从打印结果分析,因为在shell中没有其他的控件,也就是shell内含控件固定,而通过shell.computeSize()优化计算出来的结果,总是一个固定值,而不论shell size的大小。

 

解释:

shell.computeTrim(e.x, e.y, 100, 100)

0:0

Rectangle {-3, -29, 106, 132}

 

1:0

Rectangle {-2, -29, 106, 132}

从上面的两个结果来看,要想在指定位置(e.x,e.y)处得到想要的大小(100100)的clientArea,那么需要设置给shell的大小应该是(106132)。Shell的位置应该定位在(e.x – 3, e.y – 29)

 

通过:

System.out.println(shell.toControl(e.x, e.y));

System.out.println(shell.toDisplay(e.x, e.y));

结果:

0:0e.x,e.y,相对于clientArea

Point {-3, -29}

Point {3, 29}

shell相对于(e.xe.y)的位置是(-3-29.

(e.x,e.y)相对于display的位置(屏幕坐标原点)是(329)这里3恰是边框宽度,29是标题栏的宽度。这里不明白的是,clientArea上的(0,0) 对应于display的坐标上,不应该是(3,32)么?32 = 29 + 3(标题栏+border的宽度) 。

 

下面看shell的实现。有标题的shell,是可以直接拖动的,没有标题通过设置shell的location实现。

让shell实现mouseListener和MouseMoveListener两个监听器,在鼠标左键按下、弹起时分别设置两个值:

boolean LButtonDown = true/false

Point point = new Point(e.x,e.y) / new Point(0,0);

在mouseMove()方法体中,使用下面的代码:

Point oldLoc = shell.getLocation();
System.out.println("shell old loc: " + oldLoc);
System.out.println("old exy: " + point.x + ":" + point.y);
System.out.println("new exy : " + e.x + ":" + e.y);
Point dp = shell.toDisplay(e.x, e.y);
System.out.println("new to display : " + dp);
shell.setLocation(dp.x - 3 - point.x, dp.y - 29 - point.y);
System.out.println("shell new loc: " + shell.getLocation());

得到结果:

shell old loc: Point {2, 1}
old exy: 3:2
new exy : 4:2
new to display : Point {9, 32}
shell new loc: Point {3, 1}

可见在x轴增1的情况下,shell的x轴也随之增1.实现鼠标跟随。其中shell.setLocation(dp.x - 3 - point.x, dp.y - 29 - point.y);是shell在有title的情况下。如果shell没有title(这时shell的bord宽度是1)。则应该是shell.setLocation(dp.x - 1 - point.x, dp.y - 1 - point.y);

 

进一步,实现shell在一个给定的窗口中漫游。在mouseMove()方法中使用下面代码:

Point dp = shell.toDisplay(e.x, e.y);
int x = dp.x - 1 - point.x;
 int y = dp.y - 1 - point.y;
 Rectangle shellBounds = shell.getBounds();
 Rectangle bounds = viewer.getControl().getBounds();
 Point windowXy = viewer.getControl().toDisplay(bounds.x, bounds.y);
 x = x < windowXy.x ? windowXy.x : x;
 y = y < windowXy.y ? windowXy.y : y;
 int m = windowXy.x + bounds.width - shellBounds.width;
 int n = windowXy.y + bounds.height - shellBounds.height;
 x = x > m ? m : x;
 y = y > n ? n : y;
 shell.setLocation(x, y);

 

 

分享到:
评论

相关推荐

    SWT创建Shell窗口

    本篇将详细讲解如何使用SWT来创建一个基本的Shell窗口。 首先,我们需要理解Shell在SWT中的含义。Shell是SWT中的顶级窗口,类似于其他GUI库中的Frame或Window。它是应用程序的主窗口,可以包含各种控件,如按钮、...

    swt小技巧,SWT的SHELL样式

    SWT中的`Shell`样式可以通过组合不同的样式常量来实现。下面是一些常用的样式及其功能介绍: - **SWT.BORDER**:为`Shell`添加一个边框。这通常是默认行为。 - **SWT.CLOSE**:在`Shell`的右上角显示一个关闭按钮。...

    SWT中实现shell Canvas Composite等控件的背景透明

    SWT中实现shell Canvas Composite等控件的背景透明

    swt table 实现换行

    根据提供的文件信息,可以看出本文主要讨论的是如何在 SWT (Standard Widget Toolkit) 的 Table 控件中实现文本换行的功能。SWT 是一个用于开发基于 Java 的桌面应用程序的工具包,它提供了丰富的用户界面组件来帮助...

    使Excel嵌入到SWT窗口中

    SWT的使用可以大大简化GUI的开发和实现。 知识点三:OLE技术的使用 OLE(Object Linking and Embedding)是一种允许不同的应用程序之间交互和共享数据的技术。在本例中,我们使用OLE技术将Excel嵌入到SWT窗口中。...

    SWT.rar_SWT tutorial_java swt_swt 登陆窗口_swt tutori_swt-designer

    SWT,全称为Standard Widget Toolkit,是Java编程中用于创建图形用户界面(GUI)的一种开源库。它由Eclipse基金会维护,与Java Swing并行存在,提供了与操作系统更紧密的集成,使得开发者能够构建出与操作系统原生...

    Java使用SWT技术实现跳棋游戏.rar

    Java使用SWT(Standard Widget Toolkit)技术来实现的跳棋游戏是一个典型的图形用户界面(GUI)编程项目。SWT是Eclipse基金会维护的一个开源库,它提供了与操作系统原生控件紧密集成的Java GUI组件,使得开发出的...

    swt背景拖动不将图片拖出窗口

    要实现"背景拖动"功能,我们需要创建一个 SWT Shell 对象,作为我们的应用程序窗口,并在此之上设置背景图片。我们可以通过以下步骤来实现: 1. **创建Shell对象**: 首先,我们需要创建一个 `Shell` 对象,这是...

    Shell和frame窗体关闭确认窗口

    MessageBox mb = new MessageBox(shell, SWT.ICON_QUESTION | SWT.OK | SWT.CANCEL); mb.setText("确认"); mb.setMessage("确定要关闭吗?"); int rc = mb.open(); e.doit = rc == SWT.OK; } }); shell....

    SWT/JFACE客户端登录窗口例子

    在 SWT 中,这通常通过 `addSelectionListener` 方法实现,而在 JFace 中,可能会使用 `Action` 对象和 `Command` 框架。 5. **对话框(Dialog)**:登录窗口可能是一个独立的 `Dialog` 对象,它继承自 `org....

    SWT 基本 窗口 组件

    java SWT 基本窗口 组件 开发

    Java使用SWT JFreeChart控件实现的小游戏.zip

    Java使用SWT JFreeChart控件实现的小游戏.zipJava使用SWT JFreeChart控件实现的小游戏.zipJava使用SWT JFreeChart控件实现的小游戏.zipJava使用SWT JFreeChart控件实现的小游戏.zipJava使用SWT JFreeChart控件实现的...

    SWT界面化计算器

    1. Shell:这是SWT中的顶级窗口对象,相当于其他GUI库中的Frame或Window。 2. Composite:这是一个容器类,可以用来组合其他控件,构建复杂的布局。 3. Button:用于创建加、减、乘、除以及清除、等于等按钮。 4. ...

    SWT详细精解

    SWT的核心类包括Shell(顶级窗口)、Composite(容器)、Button、Text、Label等基本组件。 2. SWT组件: - Shell:所有SWT应用程序的顶级容器,相当于其他GUI框架中的 JFrame 或 Form。 - Composite:可嵌套的...

    swt实现的日历附带说明使用

    2. **创建JDatePicker对象**:在SWT的Composite或者Shell中,你可以通过创建一个JDatePicker实例来添加日历组件。这可能涉及构造函数的调用,例如 `new JDatePicker(new SimpleDateFormat("yyyy-MM-dd"), new ...

    swt的简单代码

    4. Display与Shell:在SWT中,Display是整个GUI的顶级容器,所有的窗口(Shell)都必须在Display上创建。Shell代表应用程序的窗口,它是其他组件的容器。 5. SWT与JFace:JFace是建立在SWT之上的一层抽象,提供了...

    SWT隐藏任务栏图标

    这可能涉及到SWT源码中的特定平台处理,或者可能涉及到在创建Shell后,通过系统级别的API调用来实现隐藏任务栏图标的目的。由于没有具体的代码示例,我们无法给出确切的实现细节。但是,可以明确的是,解决这个问题...

    swt 窗口设计演示

    详细描述了SWT组件的实际应用 详细在说明书

Global site tag (gtag.js) - Google Analytics