用Java获取当前活动窗口的标题

我正在尝试编写一个Java程序来记录我每5秒使用一次的应用程序(这是一个时间跟踪器应用程序)。 我需要一些方法来找出当前活动窗口是什么。 我找到了KeyboardFocusManager.getGlobalActiveWindow(),但我无法让它正常工作。 最好是跨平台解决方案,但如果不存在,那么我正在使用X.Org开发Linux。 谢谢。

我很确定你会发现没有办法在纯Java中枚举活动窗口(之前我看起来很难),所以你需要为你想要定位的平台编写代码。

  • 在Mac OS X上,您可以使用“osascript”启动AppleScript 。

  • 在X11上,您可以使用xwininfo 。

  • 在Windows上,您可以启动一些VBScript(例如, 此链接看起来很有希望)。

如果您正在使用SWT,您可能能够在SWT库中找到一些未记录的非公共方法,因为SWT为许多OS API提供了包装(例如,Cocoa上的SWT具有org.eclipse.swt.internal.cocoa.OS#objc_msgSend()可用于访问操作系统的方法。 Windows和X11上的等效“OS”类可能包含您可以使用的API。

我用user361601的脚本编写了一个java程序。 我希望这会有助于其他人。

 import java.io.BufferedReader; import java.io.InputStreamReader; public class WindowAndProcessInfo4Linux { public static final String WIN_ID_CMD = "xprop -root | grep " + "\"_NET_ACTIVE_WINDOW(WINDOW)\"" + "|cut -d ' ' -f 5"; public static final String WIN_INFO_CMD_PREFIX = "xwininfo -id "; public static final String WIN_INFO_CMD_MID = " |awk \'BEGIN {FS=\"\\\"\"}/xwininfo: Window id/{print $2}\' | sed \'s/-[^-]*$//g\'"; public String execShellCmd(String cmd){ try { Runtime runtime = Runtime.getRuntime(); Process process = runtime.exec(new String[] { "/bin/bash", "-c", cmd }); int exitValue = process.waitFor(); System.out.println("exit value: " + exitValue); BufferedReader buf = new BufferedReader(new InputStreamReader(process.getInputStream())); String line = ""; String output = ""; while ((line = buf.readLine()) != null) { output = line; } return output; } catch (Exception e) { System.out.println(e); return null; } } public String windowInfoCmd(String winId){ if(null!=winId && !"".equalsIgnoreCase(winId)){ return WIN_INFO_CMD_PREFIX+winId +WIN_INFO_CMD_MID; } return null; } public static void main (String [] args){ WindowAndProcessInfo4Linux windowAndProcessInfo4Linux = new WindowAndProcessInfo4Linux(); try { Thread.sleep(4000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } String winId = windowAndProcessInfo4Linux.execShellCmd(WIN_ID_CMD); String winInfoMcd = windowAndProcessInfo4Linux.windowInfoCmd(winId); String windowTitle = windowAndProcessInfo4Linux.execShellCmd(winInfoMcd); System.out.println("window title is: "+ windowTitle); } } 

// thread.sleep在那里,你有时间切换到其他窗口:)也可以使用spring的石英来安排它。

要在java swing应用程序中查找活动窗口(无论是框架还是对话框),您可以使用以下递归方法:

 Window getSelectedWindow(Window[] windows) { Window result = null; for (int i = 0; i < windows.length; i++) { Window window = windows[i]; if (window.isActive()) { result = window; } else { Window[] ownedWindows = window.getOwnedWindows(); if (ownedWindows != null) { result = getSelectedWindow(ownedWindows); } } } return result; } 

这是来自这里窗口状态的更多线索。

我编写了一个记录当前活动窗口的bash脚本: http : //www.whitelamp.com/public/active-window-logger.html它使用了wmctrl的修补版本,但提供了替代(较慢)方法的详细信息使用xprop和xwininfo。

可以在上面找到指向wmctrl补丁和源代码以及脚本的链接。

我在研究类似主题时创建了这个AppleScript – 这个获得了特定的窗口大小

 global theSBounds tell application "System Events" set this_info to {} set theSBounds to {} repeat with theProcess in processes if not background only of theProcess then tell theProcess set processName to name set theWindows to windows end tell set windowsCount to count of theWindows if processName contains "xxxxxxxx" then set this_info to this_info & processName else if processName is not "Finder" then if windowsCount is greater than 0 then repeat with theWindow in theWindows tell theProcess tell theWindow if (value of attribute "AXTitle") contains "Genymotion for personal use -" then -- set this_info to this_info & (value of attribute "AXTitle") set the props to get the properties of the theWindow set theSBounds to {size, position} of props set this_info to this_info & theSBounds end if end tell end tell end repeat end if end if end if end repeat end tell return theSBounds