I'm trying to create a Window class which I can use to open multiple windows, and which will automatically add an event handler to listen for the Swt.CLOSE event, and call the shell.dispose() method when it is called.
My questions are:
Do I need to listen for shell.dispose() in this case, or to only listen for display.dispose() in my main method?
Do I need to run each window in its own thread, or can all the windows share the same UI thread? I've read some reports of buggy behavior related to event handling in case of multiple windows being open.
I recommend you should always have a single UI thread, which the single Display object runs on. See SWT: single vs. multiple displays or even the Eclipse documentation on Display that strongly recommends using a single Display object:
Applications which are built with SWT will almost always require only a single display. In particular, some platforms which SWT supports will not allow more than one active display.
There are even several sample apps available (such as this one) that demonstrate multiple shells in SWT. Calling shell.dispose() when you want to close a window is the way to go.
You should only use display.dispose() when you are shutting down the entire app, basically as a 'last step' - see this example, or this one, or pretty much any snippet on the SWT Snippets page.
Edit
The Eclipse framework itself is an example of an application that can have multiple windows - it still uses a single Display, with a single UI Thread and shared event system. Eclipse documentation on Threading Issues has a basic explanation of this:
Underneath any GUI application, regardless of its language or UI toolkit, the OS platform detects GUI events and places them in application event queues. [...] It determines which window and application should receive each event and places it in the application's event queue.
Related
I have the following simple question. Is it possible for someone to have two Java Swing application windows from which events could be captured?
I have the following scenario. I have an app which runs on a touch enabled device running Windows 7. Said app spawns another child JFrame. Now, if I click on the parent frame, I get the window's focus and I can perform actions. Doing the same on the child frame also does the same getting the focus from the parent.
What I want to do, is to be able to handle click events on both screens - that is don't block the other frame when someone is interacting with the other one.
Is there a way to do something like that?
I have made a custom Vaadin 7.1 widget which displays a timer. This timer gets an initial timing from the server (using a connector) but afterwards ticks further on itself using a separate ticking thread. When using multiple ones next to each other, including ones which run another logic (countdown, etc) they visibly get desynchronized and don't tick together.
A possible solution is to simply have the widget expect a method call (e.g. expect an event to be triggered) from a single separate thread in the code using the widget. Is there something like that offered by the Vaadin framework or what would be the recommended way to do this according to the Framework's standards?
I code in java. I wrote a keylistener for the frame and it prints all the keystrokes when the frame is active, but when i minimize it or deactivate it, the program obviously stops and no keystrokes are printed. I wanted to make a small game where i enter a key and using the robot class, it presses another set of keys but this game is in flash. any idea as to how i would capture keystrokes when window is deactivated.
edit: I only code in java so is it possible using only java or at most combining it with native machine... i use windows
By its nature, Java is sandboxed by the JVM, so you will have to incorporate some kind of native methods. There already exists a very flexible and helpful library to accomplish this under open source, called JNativeHook. It's very easy to hook in, especially if you're already familiar with Swing event handlers. Same basic concept, except it leverages native code written in C. It supports all of the basic operating systems (Windows, Mac, *Nix).
So from this question In Java Swing how do you get a Win32 window handle (hwnd) reference to a window? it appears that I can get the window32 handle .
would it be possible for java.awt.Robot to send mouse/keyboard events to that window handle?
sometimes when I am sending keys via Robot, if the window gets minimized, it will start typing into other background irrelevant windows that are open. I want to prevent this by allowing Robot to send keys and mouse events to that specific window of interest.
Would it be possible to achieve the same deal in Mac and Linux as well? be able to send Robot events to those respective specific window handles?
This is a classic problem with Robot. As they have quoted in the other thread, its not possible with pure AWT/Swing. You have to get into sun's internal API or use native code. There is not getting around that problem.
It is exactly because of the problem that you have i.e. make it work across OS's is why Java has not exposed such a control.
It would be useful to know what you are using this for.
How can I disable OS-level keyboard shortcuts (e.g. Alt-Tab, Ctrl-Alt-Left/Right, etc.) on a [Ubuntu] Linux machine? I'm developing a full-screen Java Swing app and don't want the user to be able to task switch away from the program arbitrarily. It's not enough to toggle the "always on top" flag; users mustn't be allowed to switch workspaces, migrate focus or any other such things. The machine must function normally before and after the application is executed. Google says that this will require JNI or JNA but I'm looking for a bit more hand-holding.
There's no point in trying to do this in your application because any of these changes are going to need to be handled by X11 and/or the window manager since those are what respond to the commands. Assuming that you have control of the platform, choose a window manager which supports a kiosk mode. Then use the window manager's settings to start your application and enter kiosk mode.
Options for window managers which can do this include KDE or twm-kiosk.
(And if you don't have control of the platform, you're not likely to be able to have your application intercept things like ctrl-alt-backspace anyway.)
Edit:
In response to a scaled-down version of the question in which he's willing to let things like ctl-alt-backspace go and just wants most of the keys including alt-tab or other similar application switching key combinations, the following should work:
You should be able to do this using XLib's XGrabKeyboard method through JNI. This Java/XLib JNI keypress capture tutorial should be a good starting point. However, it uses XGrabKey which just passively listens for keys and does not prevent other applications from receiving them. You'll instead want to use XGrabKeyboard which actively snags all of the normal keyboard events (which, if the premise of this StackOverflow question is correct, includes the task switching keys).
Note that as a side-effect, key capture in Swing will also probably stop working because your Swing windows are going to be separate from the window you create in C. As such, you will probably have to use your JNI interface to get key presses to your program when needed. (Although I would definitely advise testing it first before writing the code.) You might be able to avoid this if you can get the window using Java AWT Native Interface to get the window ID. (Note that Swing is built on top of AWT, so this will work for Swing.) However, I'm not sure how to do this. It looks like you might be able to navigate the window tree by getting the root window from the Display and going from there to find your Window, but it's all kind of weird. It would be nice if the AWT NI just told you the window ID, but it doesn't look like it does that.
As this warning Reminder: XGrabKeyboard is not a security interface notes, this doesn't make it impossible for other programs to see the keys, but it seems likely that window managers will not be using XQueryKeyMap so it is likely to prevent task switching.