如何强制java swt程序;将自身移动到前景“中?”;?
目前使用swt时,我有时希望一个程序能够任意出现在前台(就像闹钟可能出现的那样) 通常包括以下工作(jruby): 如果壳被最小化,这会将壳带到前面 在任何时候创建一个新的shell也会将(新shell)带到最前面 不过,到目前为止还不错,如果shell没有最小化,上面的代码只会在任务栏中闪烁应用程序的图标。实际上,你第一次运行它时,它就把它带到了最前面。之后,它只会在任务栏上闪烁。那是窗户。在Linux上,它似乎只在任务栏中闪烁(ubuntu默认) 有没有人知道一种跨平台的方法可以让应用程序在swt中占据领先地位 似乎没有一句咒语能做到这一点:forceActive setActive setMinimized(false)setFocus forceFocus和setVisible 我很确定这是可能的(至少在windows中),就像E文本编辑器所做的那样。这不是swt,但至少是其他一些应用 我在想也许这是 非常感谢 相关的:如何强制java swt程序;将自身移动到前景“中?”;?,java,shell,user-interface,swt,foreground,Java,Shell,User Interface,Swt,Foreground,目前使用swt时,我有时希望一个程序能够任意出现在前台(就像闹钟可能出现的那样) 通常包括以下工作(jruby): 如果壳被最小化,这会将壳带到前面 在任何时候创建一个新的shell也会将(新shell)带到最前面 不过,到目前为止还不错,如果shell没有最小化,上面的代码只会在任务栏中闪烁应用程序的图标。实际上,你第一次运行它时,它就把它带到了最前面。之后,它只会在任务栏上闪烁。那是窗户。在Linux上,它似乎只在任务栏中闪烁(ubuntu默认) 有没有人知道一种跨平台的方法可以让应用程序在
- 这个swing示例也可能是某种类型的线索
[1] 这实际上是Windows的一项功能,可以通过Tweak UI power toy启用(至少对于Windows XP是如此)。启用时,O/S故意阻止窗口强制自己成为聚焦窗口,以阻止其“窃取焦点”。因此,抓取焦点的操作被更改为仅闪烁任务栏图标-因为O/S是根据用户的请求故意转换操作的,所以您对此无能为力(这是一件好事) 之所以这样做(可能是因为)是因为太多应用程序滥用了“带到前台”API,而这种行为既惹恼了用户,又导致他们输入错误的应用程序。
private static void onTop(Shell){
private static void onTop(Shell shell) {
int s = -1;
Shell[] shells = display.getShells();
for (int i = 0; i < shells.length; ++i) {
if (!shells[i].equals(shell)) {
shells[i].setEnabled(false);
shells[i].update();
} else {
s = i;
}
}
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
for (int i = 0; i < shells.length; ++i) {
if (i != s) {
shells[i].setEnabled(true);
shells[i].update();
}
}
}
int s=-1;
Shell[]Shell=display.getshell();
对于(int i=0;i
这对我在Windows 7和Ubuntu上很有效:
private void bringToFront(final Shell shell) {
shell.getDisplay().asyncExec(new Runnable() {
public void run() {
shell.forceActive();
}
});
}
我们的回答是:做我们需要的事情
public void forceActive(Shell shell) {
int hFrom = OS.GetForegroundWindow();
if (hFrom <= 0) {
OS.SetForegroundWindow(shell.handle);
return;
}
if (shell.handle == hFrom) {
return;
}
int pid = OS.GetWindowThreadProcessId(hFrom, null);
int _threadid = OS.GetWindowThreadProcessId(shell.handle, null);
if (_threadid == pid) {
OS.SetForegroundWindow(shell.handle);
return;
}
if (pid > 0) {
if ( !OS.AttachThreadInput(_threadid, pid, true)) {
return;
}
OS.SetForegroundWindow(shell.handle);
OS.AttachThreadInput(_threadid, pid, false);
}
OS.BringWindowToTop(shell.handle);
OS.UpdateWindow(shell.handle);
OS.SetActiveWindow(shell.handle);
}
public void forceActive(外壳){
int hFrom=OS.GetForegroundWindow();
如果(hFrom 0){
如果(!OS.AttachThreadInput(_threadid,pid,true)){
返回;
}
OS.SetForegroundWindow(shell.handle);
AttachThreadInput(_threadid,pid,false);
}
OS.BringWindowToTop(shell.handle);
OS.UpdateWindow(shell.handle);
SetActiveWindow(shell.handle);
}
有一种方法可以使它与您最初尝试的方法一起工作。实际上,您需要调用shell.setMinimized(false)
,然后调用shell.setActive()
,以恢复shell的先前状态但是,只有当外壳
真正处于最小化状态时,这才有效。所以这里是我的最终解决方案,它人为地最小化shell
,如果它还没有最小化的话。如果必须进行最小化,则成本是快速动画
shell.getDisplay().syncExec(new Runnable() {
@Override
public void run() {
if (!shell.getMinimized())
{
shell.setMinimized(true);
}
shell.setMinimized(false);
shell.setActive();
}
});
看起来你链接到的SWT bug准确地描述了你的问题,而且听起来他们似乎无法修复它。我认为这确实是windows的问题——很好。目前的解决方法是首先最小化一个shell,然后取消它的小型化(或者使用一些本机代码[通过ffi或jni]来强制它)。在Linux中,我不太确定问题出在哪里(只是在任务托盘中闪烁)。它可能在更新版本的swt.jar>=3.5中得到修复,如果您在forceForeGround上搜索,您将看到一个解决方法,无论是好是坏(我假设这是awt用于toFront方法的方法,而swt似乎没有)。我同意forceActive应该谨慎使用:)啊,是的,仍然有太多的应用程序从后台弹出,在你忙于输入其他内容时窃取输入。我以前经历过这样的数据丢失。背景应用程序弹出“你想删除废话吗?”而我正在键入其他恰好包含“是”选择器的内容。啊。不幸的是,这个变通方法在我的Windows 10副本上不起作用。
shell.getDisplay().syncExec(new Runnable() {
@Override
public void run() {
if (!shell.getMinimized())
{
shell.setMinimized(true);
}
shell.setMinimized(false);
shell.setActive();
}
});