我正在尝试编写一个Java程序来记录我每5秒使用一次的应用程序(这是一个时间跟踪器应用程序)。我需要一些方法来找出当前活动窗口是什么。我找到了KeyboardFocusManager.getGlobalActiveWindow(),但我无法让它正常工作。最好是跨平台解决方案,但如果不存在,那么我正在使用X.Org开发Linux。感谢。
答案 0 :(得分:7)
我很确定你会发现没有办法在纯Java中枚举活动窗口(之前我看起来很难),所以你需要为你想要定位的平台编写代码。 / p>
在Mac OS X上,您可以使用“osascript”启动AppleScript。
在X11上,您可以使用xwininfo。
在Windows上,您可以启动一些VBScript(例如this link看起来很有希望)。
如果您正在使用SWT,您可能能够在SWT库中找到一些未记录的非公共方法,因为SWT为许多OS API提供了包装(例如,Cocoa上的SWT具有{{1}可用于访问OS的方法)。 Windows和X11上的等效“OS”类可能包含您可以使用的API。
答案 1 :(得分:3)
我使用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在那里,你有时间切换到其他窗口:) 另外,你可以使用春天的石英来安排它。
答案 2 :(得分:2)
要在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;
}
答案 3 :(得分:2)
我编写了一个记录当前活动窗口的bash脚本: http://www.whitelamp.com/public/active-window-logger.html 它使用了wmctrl的修补版本,但提供了详细信息 使用xprop和xwininfo的替代(较慢)方法。
指向wmctrl补丁的链接&amp;源代码和脚本都可以 在上面找到。
答案 4 :(得分:0)
我在查看类似主题时创建了这个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
答案 5 :(得分:0)
使用SWT内部构件,我可以将它们组合在一起,并且看起来工作得很好:
/** @return The currently active window's title */
public static final String getActiveWindowText() {
long /*int*/ handle = OS.GetForegroundWindow();
int length = OS.GetWindowTextLength(handle);
if(length == 0) return "";
/* Use the character encoding for the default locale */
TCHAR buffer = new TCHAR(0, length + 1);
OS.GetWindowText(handle, buffer, length + 1);
return buffer.toString(0, length);
}
public static final void main(String[] args) {
try {
Thread.sleep(1000L);
} catch(InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println(getActiveWindowText());
}
打印:user interface - Get current active window's title in Java - Stack Overflow - Google Chrome