Получить заголовок текущего активного окна в Java

Я пытаюсь написать программу на Java, которая регистрирует, какое приложение я использую каждые 5 секунд (это приложение для отслеживания времени). Мне нужен какой-то способ узнать, что такое текущее активное окно. Я нашел KeyboardFocusManager.getGlobalActiveWindow(), но не могу заставить его работать правильно. Кроссплатформенное решение предпочтительнее, но если его нет, то я разрабатываю для Linux с помощью X.Org. Спасибо.


person Community    schedule 30.08.2009    source источник
comment
Вы используете оконную систему, такую ​​как KDE или Gnome? Это может быть необходимо знать, поскольку такого рода задачи обычно необходимо выполнять с помощью кода, специфичного для системы.   -  person David Z    schedule 30.08.2009


Ответы (6)


Я совершенно уверен, что вы обнаружите, что нет способа перечислить активные окна в чистой Java (раньше я довольно тщательно искал), поэтому вам нужно будет написать код для платформ, на которые вы хотите ориентироваться.

  • В Mac OS X вы можете запустить AppleScript, используя «осаскрипт».

  • В X11 вы можете использовать xwininfo .

  • В Windows вы, вероятно, можете запустить какой-нибудь VBScript (например, эта ссылка выглядит многообещающе).

Если вы используете SWT, вы можете найти некоторые недокументированные, непубличные методы в библиотеках SWT, поскольку SWT предоставляет оболочки для многих API ОС (например, SWT на Cocoa имеет org.eclipse.swt.internal.cocoa.OS#objc_msgSend() методы, которые можно использовать для получить доступ к ОС). Эквивалентные классы «ОС» в Windows и X11 могут иметь API, которые вы можете использовать.

person Matthew Phillips    schedule 01.04.2010

Я написал java-программу, используя скрипт user361601. Надеюсь, это поможет другим.

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, так что у вас есть время переключиться на другое окно :) также вы можете использовать кварц из весны, чтобы запланировать его.

person vaibhav    schedule 05.06.2012

Чтобы найти активное окно (будь то фрейм или диалог) в приложении 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;
}

это из здесь Дополнительные подсказки о состоянии окна здесь.

person Kevin Boyd    schedule 30.08.2009
comment
Однако это учитывает только окна Java, тогда как я думаю, что Стивен хочет получить глобально активное окно, независимо от того, является ли оно программой Java или нет. - person David Z; 30.08.2009
comment
Ой! Я неправильно понял вопрос! - person Kevin Boyd; 30.08.2009
comment
Дэвид прав, я хочу знать имя глобально активного окна. Таким образом, я могу автоматически отслеживать, когда я использую, скажем, firefox и когда я использую, скажем, Eclipse. - person ; 30.08.2009

Я написал сценарий bash, который регистрирует текущее активное окно: http://www.whitelamp.com/public/active-window-logger.html Он использует исправленную версию wmctrl, но предоставляет информацию об альтернативном (более медленном) методе с использованием xprop и xwininfo.

Ссылки на патч и исходный код wmctrl, а также скрипт можно найти выше.

person user361601    schedule 08.06.2010
comment
Большое спасибо за этот скрипт. - person vaibhav; 05.06.2012

Используя внутренности 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

person Brian_Entei    schedule 14.10.2018

Я создал этот яблочный скрипт, изучая аналогичную тему - этот получает определенный размер окна

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

person Henri    schedule 30.12.2014
comment
Пожалуйста, также предоставьте объяснение вашего кода, а не просто вставляйте его сюда. - person Roope Hakulinen; 30.12.2014