Swing: Steal focus from other apps (usability in OS X) - java

I have an application in java swing which runs in the system tray most of the time. The user can use the Tray Menu to perform several actions. One of those actions is to show the app window. The problem I have is with usability on OS X.
In windows, if the user brings up the app window and later switches to another app, they can switch back to my application using the taskbar. But in OS X, the app runs in a mode in which the app does not have a menu and also will not appear in the Command + Tab list.
__LSUIElement is set to true in the info.plist file
So my problem is that if the user opens the app window, later switches to another app, they cannot switch back unless they click on the window itself (which could be behind many other windows). The simplest way is for the user to open the window again using the tray icon, but since the window is already open I am unable to bring it to the front.
So, How to I take focus away from other applications and bring my window to the front?
EDIT:
My issue is not with getting the 'Application running as agent'. I already have that working. The issue I have is to get my program window to the top when its created. I am unable to do this in java.

You can call activateIgnoringOtherApps: with a true parameter when the user clicks on the icon in the menu bar (or however you open the window). You'll have to hook into Cocoa from Java, though.

The code provided in the answer to the question below did the trick
How to bring a window to the front?

After much effort trying to do the same thing, I found that the following was the simplest solution for me:
try {
String[] cmd = new String[2];
cmd[0] = "open";
cmd[1] = "/Applications/MyApp.app";
Runtime.getRuntime().exec(cmd);
}
catch(Exception ex) {
//ignore since there's nothing else that can be done
}
Essentially, I chose to execute another process through the JVM which uses the "open" command on Mac OS X to open the app that wraps the java program that created the tray icon. Telling it to open itself again causes the window to be brought to the front since it is already running.

Related

Accessing Windows dialog boxes from Selenium and java

I am testing web site functionality with Selenium using Java from Eclipse. One test is to click a "download" button, look for a popup window (this is another selenium window), respond to that window which should then cause a Windows download dialog to pop up (please see attached image).
Please note. I do not have to actually download the file. Just verify that the windows dialog popped up.
I know from experience (or at least am unaware) that Selenium can actually access the Windows download box, choose a file location and start the download. But all I need to do is verify that the download box popped up. Exiting the chromedriver will kill the download window so it won't linger but I still need to verify it was created.
Any suggestions? One thing I tried was having the task manager open. I thought I could find a process corresponding to the dialog box, but there were 119 processes before the dialog box came up as well as when it was up. So any suggestions what to do?
I could add as an aside that someone wrote a workaround to actually download the file. Instead of clicking on a button or link he pretended to be the Windows dialog box and accepted the download. That, for reasons I stated above, will not work in this instance as I have to verify the actual results of clicking the button.
Please see my attached image for an example of the dialog box.
One workaround to meet this test requirement is, once you responds to the window which results in a Windows download dialog, try performing the next action. This will result in a WebDriverException as the access to UI will be blocked by the Windows dialog. You can then catch this WebDriverException and in the catch block press escape key using Robot class in Java. Following is an example:
try {
//1) Respond to the window that results in Windows dialog box.
//2) Perform the next action on UI.
} catch (WebDriverException we) {
//3) You can capture screen shot as well at this stage.
System.out.println("Most likely Windows dialog appeared.");
//4) Press escape key using Robot class in Java
Robot r = new Robot();
r.keyPress(KeyEvent.VK_ESCAPE);
}
You can use AutoIT to check if the windows dialog appears, then save the status of the windows dialog in somewhere(eg. a temp file), then you read the status of the windows dialog using Java from Eclipse

Quitting Java program renders Mac OS X window switching non-functional

On the Mac where I do my programming, I have an app installed called BetterTouchTool that allows me to bind keyboard shortcuts to 'gestures' on my trackpad. I have bound a gesture (that doesn't have an Apple default) to the shortcut command+Q, which quits the active program. I have found this very convenient for quickly quitting programs that I am testing, so that I can get back to writing code.
However for the graphical game that I am programming, this action makes it so that I can't use a three finger swipe to switch between windows (several other gestures are also disabled). This will also happen if I go up to the menu and click quit or if I click the red x close button. The fix is to either restart my computer or (and this is really weird) to click the in-game close button which calls System.exit(0);. I know that most players will be using this but I still want to figure out why this is happening. In addition games like Minecraft on my computer don't do this.
I am using a JFrame with setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); in the code. In an attempt to fix the issue I have tried registering a com.apple.eawt.QuitHandler that calls System.exit(0); in the handler.
I have no idea what would be considered relevant code here, so whatever you would like to see, just let me know.
I figured it out. There was one rouge Thread.sleep() call in my JFrame that was somehow effecting my system.

SWT window not correctly painted in remote desktop (Windows 7)

We have an SWT application which does a time consuming calculation when pressing a button and after that opens a new window. The calculation is done in the UI thread (which is not very nice, but it is a legacy application), so during operation the window is frozen. Usually on completion of the job the new window is repainted correctly. But if the application is run on Windows 7 an I connect to that computer using Windows remote desktop, after finishing the operation the new window sometimes is not painted correctly. This happens when I do the following:
Press the calculation button
Switch to another window which overlaps my application
Switch back to my application (which is still not responding)
Wait for the calculation to be finished.
The new window opens, but the content is not painted correctly.
After minimizing and restoring the window, the repaint is done correctly.
One solution would be to set maximum details in the remote desktop settings. But this takes too much bandwidth.
I tested with SWT versions 3.4.1, 3.6.1, and 4.2.1 and remote connection from XP->Windows 7 as well as Windows 7->Windows 7.
Try using paintListener,layout or redraw and also you have to know that is a good practise to put the redrawing in the graphical thread (I mean the main loop for the SWT application).
I found out what solves my issue:
Right afer opening the new window with shell.open() I added a shell.redraw(). Could have thought about that earlier ;-)
bla
Thank you!
EDIT:
Unfortunately this did not the trick in all situations. It works only if I switch back to my application before the title bar shows the text "(Not responding)". Switching back when "(Not responding)" is already indicated in the title bar, the behaviour is as before.

Java App’s System Try icon not showing after window login [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
java 1.6 SystemTray icon does not appear on windows startup
I have java application it creates the system try icon in window OS. When I start manually it run fine. But now I put my application to window startup mean my application should run when window boot without login.
But problem is my application started and perform there tasks but it not adding the system tray icon when some one login.
And even I notice that on window boot up my application is successfully creating the TrayIcon object, creating MenuItem, adding in popup and even adding the tray icon tray.add(trayIcon); even no any exception on window bootup, but when I login
It’s not showing on system try along with time, land card icons.
I want that it should create the try icon when some one login same like when we logged in lancard tray icon appears.
Thanks
Regards
I guess that you have a timing problem. You application starts too fast and adds system tray icon before the system tray is created by OS.
Try first to call SystemTray.getTrayIcons() and print its output to log. If your icon indeed does not appear in list you are lucky. You can just try to add the icon until it appears in tray.
If it "appears" in list but you cannot see it try the following.
Add some delay before you are adding system tray. If it will help add thread that updates system try periodically. It is not so nice solution but it will work anyway even if user restarts his desktop (I am not sure it is possible in windows but it definitely possible on linux).

Opening a LWJGL window from a SWT app on Mac

I have a SWT app that opens a OpenGL window (using the LWJGL library) after a button is pressed. It is supposed to close it's main SWT window and open a new one with an OpenGL context. Works fine on Windows. On Mac, I get this error:
2010-03-05 02:28:25.315 java[1315:a07] [Java CocoaComponent compatibility mode]: Enabled
2010-03-05 02:28:25.316 java[1315:a07] [Java CocoaComponent compatibility mode]: Setting timeout for SWT to 0.100000
2010-03-05 02:28:25.317 java[1315:a07] Apple AWT Startup Exception : _createMenuRef called with existing principal MenuRef already associated with menu
2010-03-05 02:28:25.318 java[1315:a07] Apple AWT Restarting Native Event Thread
The SWT window closes and then the app hangs, with no windows open.
It looks like the SWT app doesn't shut down cleanly and leaves it's menu entries associated with it, which prevents the LWJGL window from opening. Mac OS X only wants one application menu. SWT doesn't free it's own menu and LWJGL wants to add another.
Facts:
A button in the SWT dialog is supposed to close the dialog and open a LWJGL window (org.lwjgl.opengl.Display).
The button sets a static variable in the app to tell it what to do next after the SWT window is closed, so the LWJGL window is NOT being opened from a SWT callback directly.
The button then closes the SWT window. I don't know the correct way of doing this but tried various combinations of shell.close, shell.dispose, display.close and display.dispose, none of them worked. They all close the window but the error occurs every time.
Does anyone know what could be done to make this work?
UPDATE: This simply does not work and it seems that Apple will not fix it, ever. The only way around it is to launch a new app instance and pass it a parameter that tells it to open the second window.
UPDATE 2: In this particular case, I solved the problem by using the SWT dialog for the Windows version of the app and for the Mac version, I wrote a native Cocoa dialog which invokes the JVM and runs the LWJGL app when needed. That works pretty well.
It would appear to me that the problem is not SWT creating a new window or LWJGL actually doing so. I believe the problem lies in the fact that under Mac, the application menu must be registered to the process, and for some reason or another, there is a conflict of interest between the two.
You might have some better luck juggling things around a little:
What happens when you create a LWJGL window first, then create a SWT shell?
What happens when you initialize LWJGL statically before creating a SWT shell, then proceed to create the shell and create an LWJGL window?
Incidentally, to close a SWT window, all you need to do is dispose of the Shell:
shell.dispose();

Categories