如何使用Java获取应用程序的GUI活动

时间:2014-05-30 02:24:32

标签: java user-interface netbeans java-native-interface jna

有没有办法跟踪Java中给定应用程序的gui空闲和活动。我使用C#完成了这个,参考本教程: http://www.codeproject.com/Articles/13756/Detecting-Application-Idleness 我如何用Java做到这一点?

3 个答案:

答案 0 :(得分:1)

如果您可以修改应用程序,则可以安装自己的EventQueue - http://docs.oracle.com/javase/7/docs/api/java/awt/EventQueue.html#push(java.awt.EventQueue) - 处理UI事件和绘制请求。如果无法更改应用程序,您仍然可以使用JVMTI(http://docs.oracle.com/javase/7/docs/technotes/guides/jvmti/)执行类似的操作。实施将更加困难。

答案 1 :(得分:0)

此答案适用于Windows。

以下是一些可以帮助您入门的代码段。此代码仅供参考,并不完整。完整的解决方案很漫长。

从Java跳转到本地并拨打电话 CallNtPowerInformation()请求SystemPowerInformation。 将结果传递给Java端。

    ntStatus = CallNtPowerInformation(SystemPowerInformation, lpInputBuffer, nInputBufferSize, &systemPowerInformation, systemPowerInformationSize);
    success = ntStatus == STATUS_SUCCESS;
    if (success == FALSE) {
        logErrorMessage(thisFunctionName, ntStatus);
    } else {
        SYSTEM_POWER_INFORMATION * p = (SYSTEM_POWER_INFORMATION *) &systemPowerInformation;
        javaDefineLong(env, o, "SYSTEM_POWER_INFORMATION.CoolingMode", 0, p->CoolingMode);
        javaDefineLong(env, o, "SYSTEM_POWER_INFORMATION.Idleness", 0, p->Idleness);
        javaDefineLong(env, o, "SYSTEM_POWER_INFORMATION.TimeRemaining", 0, p->TimeRemaining);
        javaDefineLong(env, o, "SYSTEM_POWER_INFORMATION.MaxIdlenessAllowed", 0, p->MaxIdlenessAllowed);
    }

对ProcessorInformation执行相同的操作。

ntStatus = CallNtPowerInformation(ProcessorInformation, lpInputBuffer, nInputBufferSize, &processorPowerInformation, processorPowerInformationSize);
    success = ntStatus == STATUS_SUCCESS;
    if (success == FALSE) {
        logErrorMessage(thisFunctionName, ntStatus);
    } else {
        int x;
        for (x=0; x!=32; x++) {
            PROCESSOR_POWER_INFORMATION * p = (PROCESSOR_POWER_INFORMATION *) &(processorPowerInformation[x]);
            if (x != p->Number) {
                break;
            }
            else {
                javaDefineLong(env, o, "PROCESSOR_POWER_INFORMATION.CurrentIdleState", x, p->CurrentIdleState);
                javaDefineLong(env, o, "PROCESSOR_POWER_INFORMATION.CurrentMhz", x, p->CurrentMhz);
                javaDefineLong(env, o, "PROCESSOR_POWER_INFORMATION.MaxIdleState", x, p->MaxIdleState);
                javaDefineLong(env, o, "PROCESSOR_POWER_INFORMATION.MaxMhz", x, p->MaxMhz);
                javaDefineLong(env, o, "PROCESSOR_POWER_INFORMATION.MhzLimit", x, p->MhzLimit);
                javaDefineLong(env, o, "PROCESSOR_POWER_INFORMATION.Number", x, p->Number);
            }
        }
    }

对SystemPowerPolicyCurrent执行相同的操作。

ntStatus = CallNtPowerInformation(SystemPowerPolicyCurrent, lpInputBuffer, nInputBufferSize, &systemPowerPolicy, systemPowerPolicySize);
    success = ntStatus == STATUS_SUCCESS;
    if (success == FALSE) {
        logErrorMessage(thisFunctionName, ntStatus);
    } else {
        SYSTEM_POWER_POLICY * p = (SYSTEM_POWER_POLICY *) &systemPowerPolicy;
        javaDefineLong(env, o, "SYSTEM_POWER_POLICY.VideoTimeout", 0, p->VideoTimeout);
        javaDefineLong(env, o, "SYSTEM_POWER_POLICY.IdleTimeout", 0, p->IdleTimeout);
        javaDefineLong(env, o, "SYSTEM_POWER_POLICY.LidClose.Action", 0, p->LidClose.Action);
        javaDefineLong(env, o, "SYSTEM_POWER_POLICY.IdleSensitivity", 0, p->IdleSensitivity);
        javaDefineLong(env, o, "SYSTEM_POWER_POLICY.PowerButton.Action", 0, p->PowerButton.Action);
    }

回到Java端。计算空闲&忙。

final long id = Java2WinPower.longs.get("SYSTEM_POWER_INFORMATION.Idleness.0").longValue();
final long is = Java2WinPower.longs.get("SYSTEM_POWER_POLICY.IdleSensitivity.0").longValue();
final float aboveT = id - is;
final float belowT = is - id;
final float hi = 100 - is;
final float lo = is;
final int a = (int) ((aboveT / hi) * 100);
final int b = (int) ((belowT / lo) * 100);

 textID.setText(a == b ? "" : a > b ? ("Idle:" + a + "%") : ("Busy:" + b + "%"));

这是一个静态视图。当然,真实的观点是动态的。

enter image description here

有空闲和忙碌程度。例如,与闲置5%相比,30%的空闲更多闲置。 忙的也一样。忙碌的50%比忙碌的5%更忙。当您允许计算机进入睡眠或休眠状态时,您在图像中看到的SleepTimer是倒数计时器。所有数据均来自操作系统。

答案 2 :(得分:0)

如果您只想监控Java应用程序的活动,Radim的答案是正确的。如果您想按照Hovercraft Full Of Eels的建议监控整个系统的用户活动,您将需要一些本机代码。您应该能够利用JNativeHook之类的东西来完成后者。