Check in Java if a certain application is in focus

java swing focus listener
how to set focus on textfield in java swing
how to set cursor focus on textbox in java
java set focus
java focus window
focus traversal policy java
java get focused component
requestfocus java

I'd like to know whether a certain application is in focus in Linux. Say it is Google Chrome. To do so, I wrote a bash on-liner which does it correctly.

xdotool search --name --class 'google-chrome' | grep $(xdotool getactivewindow)

When this command is run in terminal, it will print the id of the terminal itself. To avoid that, run the following command and select Chrome in the three seconds time span.

sleep 3; xdotool search --name --class 'google-chrome' | grep $(xdotool getactivewindow)

The problem is that when I run the above-mentioned one-liner from Java, it seems to always print nothing. Here's my code:

String cmd = "xdotool search --name --class 'google-chrome' | grep $(xdotool getactivewindow)";
Process p = Runtime.getRuntime().exec(cmd);
String result = getCommandResult(p.getInputStream());

private static String getCommandResult(InputStream stream) throws IOException {

    StringBuilder sb = new StringBuilder();
    try (InputStreamReader isr = new InputStreamReader(stream);
         BufferedReader in = new BufferedReader(isr)) {

        String line;
        while ((line = in.readLine()) != null) {
            sb.append(line);
        }
    }
    return sb.toString().trim();
}

I'm open to different solutions to resolving this problem.

As barti_ddu said, this is not working because of the pipe in the command. You can workaround this by creating one sh process with your command passed as the argument:

    String cmd = "xdotool search --name --class 'google-chrome' | grep $(xdotool getactivewindow)";
    Process p = new ProcessBuilder("sh", "-c", cmd).start();
    String result = getCommandResult(p.getInputStream());

Learning Java, A component normally receives focus when the user clicks on it with the mouse. on some platforms that prevent focus transfer from native applications to Java focus explicitly, the only way to verify when a component has received or lost  (in java.awt.Container) Checks or sets whether a container is the root of a focus traversal cycle. isFocusTraversalPolicyProvider() setFocusTraversalPolicyProvider(boolean) (in java.awt.Container) Checks or sets whether a container will be used to provide focus traversal policy.

If You are using pipe redirection, then You either have to invoke the shell, or redirect the output from one program to another yourself.

However, IMHO, You do not need grep at all, just:

  1. Enumerate windows of certain class.
  2. Get the active window id and check if the active window list contains it.

Example (q&d, resource/error handling omitted):

private static List<String> exec(String... args) throws IOException {
    List<String> result = new ArrayList<>();
    String line;

    BufferedReader reader = new BufferedReader(
            new InputStreamReader(
                    new ProcessBuilder()
                            .command(args)
                            .start()
                            .getInputStream()));

    while ((line = reader.readLine()) != null) {
        result.add(line);
    }

    return result;
}

public static void main(String[] args) {
    try {
        Thread.sleep(3000);

        String windowId = exec("xdotool", "getactivewindow").get(0);
        System.out.println(windowId);

        List<String> windowList = exec("xdotool", "search", "--name", "--class", "google-chrome");
        System.out.println(windowList.contains(windowId));
    } catch (IOException | InterruptedException e) {
        e.printStackTrace();
    }

How to detect whether my Java application is active?, Use the focus subsystem, as documented here. An example of detecting focus being gained: //Make textField get the focus whenever frame is  (in java.awt.event.ComponentEvent) Returns the component that fired the focus event. Component getOppositeComponent() Returns the other component involved in the focus change. For a FOCUS_GAINED event, this is the component that lost the focus. For a FOCUS_LOST event, this is the component that gained the

Why are you hard coding the command into your class? Rather put your command in a shell script and call that instead. Then you have the flexibility to change the command without having to re-compile.

Process proc = Runtime.getRuntime().exec("./opt/scripts/myscript.sh");

... depending on your application, it would potentially be even better to pass in the shell script as parameter.

private void runCommandLine(String script) {
    try {
        Process proc = Runtime.getRuntime().exec(script);
        proc.waitFor();
        int character;
        while((character = proc.getInputStream().read()) != -1)  {
            System.out.write(character);
        }
        while((character = proc.getErrorStream().read()) != -1) {
            System.err.write(character);
        }
    } catch (IOException | InterruptedException e) {
        e.printStackTrace();
    }
}

EDIT:

If you goal is to figure out what window is currently in focus, then instead of trying to execute something via the command line, you could just use the JNA (Java Native Access) libraries to potentially do this.

Find out what application (window) is in focus in Java

Java Native Access (Github)

Java Swing, Focus traversal How does Swing know when it's time to move focus from one The specific keys used to signal such intentions are up to individual plat- forms to determine which component starts out with the focus (unless the application  From within my java progam, I launch a seperate Windows program. Currently, I do a setVisible(false) on my java program's GUI, execute the program ,and when it exits, i setVisible(true). The problem I have is that when I launch this other program, it comes up behind all the other windows.

A full-blown Java application (115K rows) and its source code, checkIxanosInstallation(); // Check Ixanos Libraries and Directories _msgTmp += ip. requestFocusInWindow(); // pass focus back to active Panel //if (sh. JavaScript focus method is used to give focus to a html element. It sets the element as the active element in the current document. It can be applied to one html element at a single time in a current document. The element can either be a button or a text field or a window etc. It is supported by all the browsers. Syntax: HTMLElementObject.focus()

Java Foundation Classes in a Nutshell: A Desktop Quick Reference, Just as a screen may contain many application windows, a single application A Swing component can be operated from the keyboard when it has the focus. The user can usually direct keyboard focus to a given component by clicking on that You can determine the behavior of a container by calling isFocusCycleRoot(). In this article, I summarized 4 important logs that you should know as a Java developer: The application log is the most obvious one. It’s written by your application and you are responsible for its content. If you deploy your application into a web or an application server, you also need to know about the logs provided by that server.

Focus on Indonesia, In addition, the import of certain materials is restricted to approved importers. Where the invoice price is less than the check price, duty is assessed on the check can be derived, of scrap paper from Java and Madura and of certain kinds of live, Applications for a visitor's visa valid for three months are sent by embassies  Hi, How to set the focus to a component in Swing. I used the requestFocus() it's not working. Also i have heard that it produces undesiarable result's.

Comments
  • Why does your question contain parts of additional notes that look like a copy&paste from this answer: How to get window id from xdotool Window Stack ?
  • @Tom, I'm not a native speaker so to be understood I copied and modified Note that running that command in the terminal will always return the idof the terminal windo as it is an active window. In order to get the id of another window try:. Anything else, especially the code, is mine. Is this a problem for you? (I rewrote the text using my own words).
  • See also When Runtime.exec() won't for many good tips on creating and handling a process correctly. Then ignore it refers to exec and use a ProcessBuilder to create the process. Also break a String arg into String[] args to account for things like paths containing space characters.
  • Or nearer at hand stackoverflow.com/questions/31776546/… and maybe stackoverflow.com/questions/5928225/… and stackoverflow.com/questions/2088917/…