Some background:
I have a turn based game where you can play several concurrent games in separate windows. Each window/game has it's own chat and also a kind of game action panel that turns up when it's your turn to act.
The issue:
Game windows will steal focus whenever it becomes your turn to act in any of the games you're playing, this is by design but very annoying if you're involved in chatting at any of your games because when focus is lost that chat will no longer receive your key board strokes.
What I want:
Some way to dispatch key board events to a JTextField that's no longer the focus owner (and also in a different window/JFrame than the current focus owner). Is there some way to do this? And how?
Plan b would be to set some kind of timer on the chat and let the window refuse to give up focus until x amount of time has passed since the last key stroke in the chat, but it might not be ok to stall the focus switch since your action time is limited already.
You can set alwaysOnTop of the current chat window true while there's text in the chat text field by calling:
java.awt.Window
public final void setAlwaysOnTop(boolean alwaysOnTop)
throws SecurityException
When user presses Enter or clicks on Send button reset the alwaysOnTop so other windows could steel the focus.
I might have found what I was looking for here. Remains to be seen if I'll try to use it or if we'll change the requirements :)
See this link to find a working SSCCE on how to redispatch KeyEvents to any text component.
Related
I'm trying to make an overlay on the screen using JavaFX and an issue I'm having is that whenever my overlay pops up, it steals focus from whichever program I'm currently in. The issue with this is that my overlay allows the user to simulate keyboard key presses using the robot class (like an on-screen keyboard) and without keeping the focus in the original window, the typed characters have nowhere to go. I've tried setting the modality to none, but that's also the default option and it doesn't seem to be doing anything. Would putting my JavaFX scene in a JFrame work or is there some better way to do it only in JavaFX?
Try this
when focused -> compute what you want to
then call Stage.toBack(); //the currently focused window prior to yours will gain focus back
I'm building a Swing game that is drawn entirely (everything, menus included) in single JPanel object. I have a game loop in this JPanel, which handles everything from updating the state of the game to drawing it and so on.
Now, I need to somehow enable the player to type in their own text in some of the menus. Creating a new player profile, saving some other information and the like. I can't seem to find a good way for doing this. Using a Scanner is obviously out of the question, since doing that will interrupt the event dispatching thread, freezing the game on the spot (I learned that the hard way).
I have concluded that the only way to do this is to use the KeyListener to somehow record the keys I have pressed on the keyboard. I have been experimenting with its keyTyped method, but my results have been poor. I have been able to make it record my keypresses, but the problem is, it records EVERY key I have pressed, including backspace, control, TAB, and so on... Plus, every character that I type is outputted capitalized, regardless of whether I have Caps Lock on or not.
I hope you understand what I'm trying to achieve here. So my real question: Is there any easy way to record typing using KeyListener? Or is there some other way that can be used inside of the event dispatching thread?
Your options are:
Use a standard popup dialog and get your text that way
Embed a text field into your panel to receive input
The problem is that a KeyListener is just that, it listens for key events. The standard text input components combine this with a DocumentListener for processing text
Quick question, I have 3 JPanels, one has a keylistener and it draw my game graphics, and you can alter it by moving your character around, etc. and I have a second JPanel which is just a JTextArea, and it just displays text, and finally I have another JPanel which has a JTextArea and a JButton, the text area takes inputs and you may hit enter key or click the button to send the text which will appear in the other text box. But my question is, how can I request focus in each panel? How do i transfer the focus with lets say a mouse click?
I know that if I dont constantly call requestFocus(true); for the first JPanel with displays all the graphics it wont work for some reason. I believe its because its always painting and maybe it looses focus on every go around. But how to I in all get the focus to transfer with a mouse click, etc?
One possible solution is to not use a KeyListener. Instead use Key Bindings which are much more forgiving with regard to focus. Have a look at the Key Bindings tutorials which Google can help you find in a jiffy.
For more specific help, consider creating and posting an sscce.
Just wondering what focus means in java code, because I have seen onWindowFocusChanged, addFocussables, findFocus...
If I have a scrollable list and I scrolled it down, the first item will have focus false? or it means other thing?
Thanks
Focus means you have selected the particular GUI element. For example when you select a window that window gains focus, when you select another window the first window loses focus.... It's the same for JTextField, JTextArea, etc.
The definition of the focus here on StackOverflow is as follows:
Focus indicates the component of the graphical user interface which is
currently selected to receive input.
Saying that focused component is selected is not accurate. For instance, we can have a JCheckBox which is deselected (has no tick mark) and it is also the current focus owner. Since it has focus, its state is toggled with the spacebar. The term active is more precise. I came up with the following definition of focus:
Focus is a state of a component in which it receives keyboard input. Focus is represented by some visual cue; for instance, in Metal look and feel a focused JButton has a blue rectangle around its label. The component with the current input focus is called the focus owner.
The current GUI element that is "active" has the focus. For example when you have several Input windows only one can have the focus and receive your keyboard input. See here the Android GUI doc http://developer.android.com/guide/topics/ui/ui-events.html
I writing an application which controls another application by using the keyboard only. To more concrete, the application simulates key presses and mouse clicks when a certain key is pressed on the keyboard. For example, pressing on the 'x' key simulates a mouse click on the [X] in the rop right corner, followed by a little sleep of 2 seconds and an 'enter' to confirm the exit dialog. Pretty easy. I am developing this application in Java.
Sending a key press or a mouse click is very easy with java.awt.Robot. I am facing one little problem. Say I have configured a key which will click somewhere on the screen. The problem is that consecutive key presses aren't catched anymore, as my application lost its focus caused by the mouse click outside it's window.
My question now is: what is the best way to be sure that my main application keeps the focus? Is there a way to focus my application again after the key presses and mouse clicks are sent out? Is there a better way?
Thanks in advance.
If your application lost the focus. because you or your Robot clicked to somwhere else, the Robot must click on the application again before sending a new key. In c/c++ you could force the focus to the application (a non-trivial task), not in Java!
You might want to take a look at Component.requestFocus() to see if can do what you want.
Be aware however that window focusing has very platform dependent behaviour, so you will probably need to do quite a bit of testing to ensure that your code does what you want in all circumstances.
I managed a way to prevent applications from losing all focus in Java.
By placing a WindowFocusListener on the frame (or dialog) and calling setVisible(false) followed by setVisible(true) in windowLostFocus the component will re-appear as soon as it is dissapears (not the prettiest solution but it does work).
By then calling component.requestFocus() your robot should be able to continue where it left off