在 Windows 中使用 Java 将焦点设置到非 Java 应用程序

Posted

技术标签:

【中文标题】在 Windows 中使用 Java 将焦点设置到非 Java 应用程序【英文标题】:Using Java to set the focus to a non Java application in Windows 【发布时间】:2011-01-24 12:56:50 【问题描述】:

我想编写一个为 Windows 中的非 Java 应用程序创建输入的应用程序。使用 Robot 类很容易生成输入,但我需要将焦点设置到另一个应用程序的文本框并在那里输入文本。

别担心,我不是想写一些恶意的东西,我只是想用 Java 来“扩展”一个用 Delphi 编写的旧应用程序。

【问题讨论】:

另一种选择是我的 Java 应用程序永远不会获得焦点,因此 Windows 应用程序具有焦点,并且当您单击 Java 应用程序上的按钮时,焦点永远不会在原始窗口中丢失。我不知道这是否可能? 对于那些通过谷歌在 OSX 上提出这个问题的人:***.com/questions/14859733/… 【参考方案1】:

CMDOW 是一个命令行实用程序,可让您执行各种窗口操作,例如激活/停用、列出、最小化/最大化等。

或者,您可以编写一个 VBScript 来激活另一个应用程序。例如:

Set WshShell = WScript.CreateObject("WScript.Shell") 
WshShell.AppActivate("Firefox")

然后在您的 Java 应用程序中使用 Runtime.exec 来执行脚本。

这将帮助您激活另一个应用程序。

但是,如果您想专注于其他应用程序中的文本框并编写一些文本,这将更加困难。

【讨论】:

不得不说我喜欢 CMDOW 但我注意到 2 个问题.. 非常慢.. 在我过载的热节流系统上 - 现在订购一个新风扇 - 所以对于大多数用户来说不知道它是否会很明显,但是 nircmd 的工作速度要快得多.. 所以只是让人们知道 nircmd 也是一个选项 - 不支持通配符,但您可以指定子字符串是否匹配或从标题的开头或结尾。此外,我无法使用相同的子字符串激活多个窗口,nircmd 可以做到这一点.. 所以出于这两个原因,我选择了 nircmd.. @dogbane 你知道 linux 操作系统有类似的东西吗?【参考方案2】:

检测一个特殊的应用程序并将它放在前面可能需要一个本地帮助程序,但目前您可以发送 ALT+TAB 来激活“下一个”应用

这行得通:

public void switchFocus() 
  try 
    Robot r = new Robot();
    r.keyPress(KeyEvent.VK_ALT);
    r.keyPress(KeyEvent.VK_TAB);
    r.keyRelease(KeyEvent.VK_ALT);
    r.keyRelease(KeyEvent.VK_TAB);
   catch(AWTException e) 
    // handle
  

你只需要实现一个方便的方法来将字符(从字符串)映射到关键事件值......(或找到一些现有的解决方案)

【讨论】:

【参考方案3】:

配置延迟,否则不起作用:

Robot r = new Robot();
r.keyPress(KeyEvent.VK_ALT);
r.keyPress(KeyEvent.VK_TAB);
r.delay(10); //set the delay
r.keyRelease(KeyEvent.VK_ALT);
r.keyRelease(KeyEvent.VK_TAB);

【讨论】:

【参考方案4】:

在 Mac 上,可以使用 AppleScript 来完成。 AppleScript 已集成到系统中,因此它始终可以正常工作。 https://developer.apple.com/library/content/documentation/AppleScript/Conceptual/AppleScriptLangGuide/reference/ASLR_cmds.html

您只需要检测您是否在 mac 上并具有应用程序的名称。

Runtime runtime = Runtime.getRuntime();
            String[] args =  "osascript", "-e", "tell app \"Chrome\" to activate" ;
            Process process = runtime.exec(args);

【讨论】:

【参考方案5】:

您需要为应用程序添加足够的延迟才能完全初始化并获得焦点。

这是一个基本的工作示例...Andreas_D 是正确的,您需要模拟系统键才能在程序之间切换...(Alt+Tab on Windows,Cmd+Tab 在 OS X 上)

    import java.awt.*;
    import static java.awt.event.KeyEvent.*;
    import java.io.IOException;

    public class RobotSample 

        //https://***.com/questions/4782231
        private static Integer[] KEY_CODES =  VK_S, VK_T, VK_A, VK_C, VK_K, VK_O, VK_V, VK_E, VK_R, VK_F, VK_L,VK_O, VK_W, VK_DECIMAL, VK_C, VK_O, VK_M, VK_SLASH, VK_Q, VK_U, VK_E, VK_S, VK_T, VK_I, VK_O, VK_N, VK_S, VK_SLASH, VK_4, VK_7, VK_8, VK_2, VK_2, VK_3, VK_1, VK_ENTER ;

        public static void main( String[] args ) throws IOException 

            try 
                Robot robot = new Robot();
                Runtime runtime = Runtime.getRuntime();

                runtime.exec( "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe" );

                robot.keyPress( VK_ALT );
                robot.keyPress( VK_TAB );
                robot.keyRelease( VK_ALT );
                robot.keyRelease( VK_TAB );

                //Chill a sec...
                robot.delay( 1000 );

                for(int i = 0; i <  KEY_CODES.length; ++i) 
                    robot.keyPress( KEY_CODES[i] );
                    robot.keyRelease( KEY_CODES[i] );
                    robot.delay( 80 );
                    

             catch( AWTException e ) 
                e.getMessage();
            

        

    

【讨论】:

以上是关于在 Windows 中使用 Java 将焦点设置到非 Java 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

在OpenGL中更改焦点时Windows闪烁

菜单栏程序 - 将焦点设置到第 3 方应用程序

防止视图窃取焦点/将焦点设置到视图

如何使用 JavaScript 将焦点设置在 HTML 表单中的元素上?

如何在winform c#中禁用按钮时将焦点设置在按钮上?

将键盘选项卡焦点设置到页面顶部/使用 JavaScript / jQuery 重置键盘焦点