Ich versuche ein Java-Programm zu schreiben, das alle 5 Sekunden protokolliert, welche Anwendung ich verwende (dies ist eine Zeit-Tracker-App). Ich brauche einen Weg, um herauszufinden, was das aktuelle aktive Fenster ist. Ich habe KeyboardFocusManager.getGlobalActiveWindow() gefunden, aber ich kann nicht richtig funktionieren. Eine plattformübergreifende Lösung ist vorzuziehen, aber wenn es keine gibt, dann entwickle ich für Linux mit X.Org. Vielen Dank.Aktuellen Titel des aktiven Fensters in Java abrufen
Antwort
Um das aktive Fenster zu finden (sei es ein Rahmen oder ein Dialog) in einer Java-Swing-Anwendung, die Sie die folgende rekursive Methode verwenden können:
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;
}
Das berücksichtigt nur Java-Fenster, während ich glaube, Steven möchte das global aktive Fenster bekommen, egal ob es ein Java-Programm ist oder nicht. –
Hoppla!Ich habe die Frage missverstanden! –
David hat recht, ich möchte den Namen des global aktiven Fensters wissen. Auf diese Weise kann ich automatisch den Überblick behalten, wenn ich zum Beispiel Firefox benutze und wenn ich zum Beispiel Eclipse benutze. –
Ich bin ziemlich sicher, dass es keine Möglichkeit gibt, die aktiven Fenster in reinem Java aufzuzählen (ich habe schon ziemlich lange nachgesehen), also müssen Sie für die Plattformen programmieren, auf die Sie zielen wollen.
Unter Mac OS X können Sie eine AppleScript mit "osascript" starten.
Auf X11 können Sie xwininfo verwenden.
Unter Windows können Sie wahrscheinlich einige VBScript starten (z. B. this link sieht vielversprechend aus).
Wenn Sie SWT verwenden, können Sie in der Lage sein, einige nicht dokumentierte, nicht-öffentliche Methoden in den SWT-Libs zu finden, da SWT-Wrapper für viele der API OS bietet (zB SWT auf Cocoa hat die org.eclipse.swt.internal.cocoa.OS#objc_msgSend()
Methoden, die verwendet werden können, um auf das Betriebssystem zuzugreifen). Die entsprechenden "OS" -Klassen für Windows und X11 können über APIs verfügen, die Sie verwenden können.
Ich habe einen Bash-Skript geschrieben, das die aktuellen aktiven Fenster protokolliert: http://www.whitelamp.com/public/active-window-logger.html Es verwendet eine gepatchte Version von wmctrl sondern bietet Details von eine Alternative (langsamer) Methode xprop und xwininfo verwenden.
Die Links zum wmctrl Patch & Quellcode und das Skript können oben gefunden werden.
Vielen Dank für dieses Skript. – vaibhav
funktioniert jetzt nicht (2014-06-16). – VasyaNovikov
Ich habe ein Java-Programm mit user361601-Skript geschrieben. Ich hoffe, dass dies anderen hilft.
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);
}
}
// die Thread.Sleep ist, so dass Sie Zeit, um andere Fenster zu wechseln bekommen :) auch, können Sie Quarz vom Frühling verwenden Sie es zu planen.
habe ich diesen Apple während in ähnliches Thema suchen - das bekommt man die spezifische Fenstergröße
global theSBounds
tell application "System Events"
\t set this_info to {}
\t set theSBounds to {}
\t repeat with theProcess in processes
\t \t if not background only of theProcess then
\t \t \t tell theProcess
\t \t \t \t set processName to name
\t \t \t \t set theWindows to windows
\t \t \t end tell
\t \t \t set windowsCount to count of theWindows
\t \t \t
\t \t \t if processName contains "xxxxxxxx" then
\t \t \t \t set this_info to this_info & processName
\t \t \t \t
\t \t \t else if processName is not "Finder" then
\t \t \t \t if windowsCount is greater than 0 then
\t \t \t \t \t repeat with theWindow in theWindows
\t \t \t \t \t \t tell theProcess
\t \t \t \t \t \t \t tell theWindow
\t \t \t \t \t \t \t \t if (value of attribute "AXTitle") contains "Genymotion for personal use -" then
\t \t \t \t \t \t \t \t \t -- set this_info to this_info & (value of attribute "AXTitle")
\t \t \t \t \t \t \t \t \t set the props to get the properties of the theWindow
\t \t \t \t \t \t \t \t \t set theSBounds to {size, position} of props
\t \t \t \t \t \t \t \t \t set this_info to this_info & theSBounds
\t \t \t \t \t \t \t \t end if
\t \t \t \t \t \t \t end tell
\t \t \t \t \t \t end tell
\t \t \t \t \t end repeat
\t \t \t \t end if
\t \t \t end if
\t \t end if
\t end repeat
end tell
return theSBounds
Bitte erläutern Sie auch Ihren Code, anstatt ihn einfach hier einzufügen. –
Es gibt eine Erklärung. Wenn du nicht magst, was ich gepostet habe oder nicht ein paar Minuten verbringen willst, um zu sehen, was das Skript macht, dann lösche den Beitrag blutig. – Henri
Sie ein Windowing-System wie KDE oder Gnome verwenden? Es kann notwendig sein, dies zu wissen, da diese Art von Aufgabe normalerweise mit systemspezifischem Code ausgeführt werden muss. –
Gnome ist meine erste Priorität. –