- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我想创建一个“选择区域”工具。此工具应允许使用鼠标在屏幕上绘制一个矩形区域。
我使用全屏、半透明、变暗的 swt Shell
作为我的背景,我在其上绘制了一个白色矩形来表示所选区域。
我的问题是我没有找到刷新矩形区域的有效方法。直到现在我都使用了 redraw
方法但是视觉效果非常丑陋,甚至认为我试图只重绘他需要的区域:
public ManualScreenAreaSelector(final Display display) {
shell = new Shell(display, SWT.NO_TRIM | SWT.ON_TOP);
shell.setBounds(display.getClientArea());
// shell.setFullScreen(true);
shell.setAlpha(180);
shell.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
shell.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
}
@Override
public void mouseMove(final MouseEvent e) {
if (editionMode) {
// retrieve the rectangular area corresponding to mouse selection
final Rectangle r = makeRectangleFromSelection(clickCoordinates, new Point(e.x, e.y));
// make the ugly 'tint' effect
shell.redraw();
GC gc = new GC(shell);
gc.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE));
gc.setAlpha(150);
gc.fillRectangle(r.x, r.y, r.width, r.height);
gc.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK));
gc.fillRectangle(0, 0, r.x, r.y);
gc.fillRectangle(0, 1080 - r.y, r.x, 1080 - r.y);
gc.dispose();
lastX = e.x;
lastY = e.y;
}
}
@Override
public void mouseDown(final MouseEvent e) {
// Right click = reset selection
if (e.button == 3) {
shell.redraw();
selectedArea = null;
if (editionMode) {
editionMode = false;
shell.removeMouseMoveListener(ManualScreenAreaSelector.this);
}
} else if (e.button == 1) {
// left-click enter edition mode
// Reset previous selection
selectedArea = null;
editionMode = true;
clickCoordinates = new Point(e.x, e.y);
lastX = e.x;
lastY = e.y;
shell.addMouseMoveListener(ManualScreenAreaSelector.this);
}
}
@Override
public void mouseUp(final MouseEvent e) {
// left click, only if edition was set
if ((e.button == 1) && editionMode) {
editionMode = false;
shell.removeMouseMoveListener(ManualScreenAreaSelector.this);
selectedArea = makeRectangleFromSelection(clickCoordinates, new Point(e.x, e.y));
shell.dispose();
}
}
所以我想知道在 SWT 中是否存在更有效的解决方案,而不必使用重绘方法。
编辑我使用了 3 张图像来进行选择:
性能是可以接受的,因为只有一个 alpha 混合操作(对于第二张图像)。
只有一个问题仍然存在,当我第一次使用 shell 的图形控件绘制 shell 时,alpha 混合图像未用作 shell 背景,发送鼠标事件时其他一切正常:
public ManualScreenAreaSelector(final Display display) {
screenWidth = display.getClientArea().width;
screenHeight = display.getClientArea().height;
// create a new Image of the screen
backGround = new Image(display, display.getBounds());
GC gc = new GC(display);
gc.copyArea(backGround, 0, 0);
gc.dispose();
// Copy background image and add alpha blended effect
aplhaBackGround = new Image(backGround.getDevice(), backGround.getImageData());
GC alphaGC = new GC(aplhaBackGround);
alphaGC.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
alphaGC.setAlpha(200);
alphaGC.fillRectangle(0, 0, screenWidth, screenHeight);
alphaGC.dispose();
// create the shell
shell = new Shell(display, SWT.NO_TRIM | SWT.ON_TOP | SWT.NO_BACKGROUND);
shell.setBounds(display.getClientArea());
// get shell graphics control
shellGraphics = new GC(shell);
// set the shell image to screen image <-- does nothing
shellGraphics.drawImage(aplhaBackGround, 0, 0);
// Image for the shell
bufferImage = new Image(shell.getDisplay(), shell.getBounds());
shell.print(shellGraphics);
}
public void mouseMove(final MouseEvent e) {
if (editionMode) {
// Get selected area
final Rectangle selectedArea = makeRectangleFromSelection(clickCoordinates, new Point(
e.x, e.y));
// Copy alpha blended background into the buffer
GC gc1 = new GC(aplhaBackGround);
gc1.copyArea(bufferImage, 0, 0);
gc1.dispose();
// Paint "normal" background over selected area
GC gc2 = new GC(bufferImage);
gc2.drawImage(backGround, selectedArea.x, selectedArea.y, selectedArea.width,
selectedArea.height, selectedArea.x, selectedArea.y, selectedArea.width,
selectedArea.height);
// draw the painted image on the shell
shellGraphics.drawImage(bufferImage, 0, 0);
gc2.dispose();
}
}
最佳答案
试试这个方法:
代替 shell.redraw();
,调用一次 shell.print(gc)
并将 GC 附加到图像缓冲区。这为您提供了外壳的图像。
获取 SWT 的 OpenGL 扩展或 jogl .将图像放在背景中并为选区创建一个 3D 矩形。使用 OpenGL 进行 alpha 操作和合成。
原因是 SWT 中的 alpha 操作速度很慢,这通常需要使用 CPU 来完成。您的显卡每秒可以执行数百次相同的操作,而不会出汗。
关于java - SWT 在外壳上绘制一个 "transparent"矩形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9586112/
快速简单的问题: 如何制作多种颜色的开关/外壳。 我能做的是: if(color == Color.Red) color = Color.Green; else { if(color
我有这个 switch/case 结构: public void onClick(View arg0) { // TODO Auto-generated method stub swi
在我的程序中,我想使用不同的进程访问多个 linux shell。 目前我正在使用子进程我目前没有 linux 机器来测试它所以你能告诉我这是否有效。 子进程是否在一个终端上工作?如果是这样,还有其他
我在后面的代码中有三次与此示例非常相似的代码。每次开关关闭发送给它的选项。每个time case里面的代码除了一个参数是完全一样的基于案例。使用 switch/case 和方法是最好的方法去做这个?我
阅读 LTP shell code它使用奇怪的 for 循环语法: for arg; do TCID="${TCID}_$arg" done 它如何接受参数?我希望它循环遍历 $arg,用 $
这不是最有见地的问题,但我真的希望能够按 Control-L 并让 shell iex 清除屏幕。知道如何做到这一点,或者是否有另一个带有此内置功能的 Elixir shell ? 最佳答案 clea
我已经切换到 Enthought 的 Canopy 1.0.0,但我想念独立的 QT shell 和 QT notebook。我不想使用 IDE 中的内置 shell。我在哪里可以找到 QT shel
我在PyCharm中创建了新的flask项目,但看不到如何在集成的PyCharm python控制台窗口中运行flask shell。 启动控制台时未定义名称应用程序: 我仍然可以在集成的PyChar
尝试创建Prism shell 时,出现以下异常: An exception of type 'Microsoft.Practices.ServiceLocation.ActivationExcept
这个问题在这里已经有了答案: How to use the switch statement in R functions? (4 个回答) 4年前关闭。 我有一系列嵌套 if..else我想用 ca
cat < file.txt < file2.txt 我正在编写一个简单的 shell,我正在思考上面的表达式的含义。我很清楚这是什么意思:cat < file.txt,但双“<”让我困惑。 实现重定
我正在考虑使用 CompositeWPF ( http://www.codeplex.com/CompositeWPF ) - 又名 Prism,来构建我正在处理的应用程序。 该应用程序不是传统的 L
我有一个没有图形用户界面的操作类。该类主要是做数据管理。该类是从我的主 GUI 中的方法调用的。我遇到的问题是在出现故障时向用户显示消息。我正在使用 MessageDialog,但它在运行时一直失败。
我在教程中看到了两种在 BASH shell 中对 if 语句进行语法处理的方法: 除非我在变量周围加上引号并添加额外的 [ 和 ],否则这个不会工作: if [[ "$step" -eq 0 ]]
我的脚本接受键值对作为命令行参数。我测试给定数量的参数是否偶数。如果偶数,我想遍历数组,将 args[n] & args[n+1] 视为一对 (n = 0 to $# - 1) 并执行另一个将这两个作
全部!我的 CKEditor 有问题!我需要用 div 将 ul、ol 列表括起来。因此,当我按下面板上的列表按钮时,我会得到这样的结果: 最佳答
我在更改我的 Android 外壳中的所有者时遇到了一些问题。我正在尝试更改文件的所有者和组以匹配目录中的另一个文件。当我 ls -l 其他文件拥有 u0_a49 的所有者时,我尝试 su chown
平台:RHEL7 情况: JMeter 报告文件每 5 分钟通过 crontab 脚本附加新结果 另一个 awk 脚本查找响应时间大于 500 毫秒并发送电子邮件警报 问题陈述: 要求是只扫描报告文件
对于 Python,我使用 PyCrust,这是一个很好的图形外壳,感觉就像一个很好的 Java IDE(具有自动完成、内联文档并可以保存历史记录)。 Ruby 有类似的东西吗? 最佳答案 如果不需要
以下出现在我的 WinProc 中: if(message == WM_CREATE) { //Do WM_CREATE stuff } else { switch(message)
我是一名优秀的程序员,十分优秀!