I', currently trying to figure out how to implement an ingame chat.
The standard use case would be: While playing, player A decides to send a chat message to his opponent. He hits ENTER, types his message, hits ENTER and the message is being displayed one the screen. Sending multiple message then should result in all the messages being displayed one after another separated by line breaks.
So what I did is using swing components:
- a JTextArea for the display area
- a JTextField for the input field
These are correctly arranged in a JPanel and implement the desired behaviour on sending messages.
The ChatPanel is added to the JDesktop of a JMEDesktopState.
Unfortunately I have trouble understanding how to integrate this into the game:
First (GameControlManager and Controls)
I use a GameControlManager for controls. But as I type the chat message, all those controls need to be disabled. Otherwise they are still triggered while typing chat messages, which leads to rather funny behaviour.
Where would one place the controls for entering and exiting chat mode. Is it necessary to disable and enable all controls one at a time or is it my misunderstanding of the use of the GameControlManager?
Second (Swing Focus)
I’m having trouble keeping the Focus in the input field. Swing seems to be incapable of doing what I intend, as documented here: Bug: requestFocus in focusLost does not work in Swing.
So clicking anywhere outside the input field will get the focus lost while the game still assumes that a chat message is being entered. Of course one could abort chatting in that case, but in my opinion this would be rather odd. In any case this would involve some additional Object references where they are unneeded otherwise.
Maybe to state more precise questions:
(1) How to organize controls for flexible context switches (game controls while not chatting, no game controls while chatting…)
(2) Would you use swing components and JMEDesktopState for ingame chat or is there another (better?) way?
Well, the way I accomplish this is by having a custom input control class and using fengGui. I have to monitor if the cursor is over a GUI component or not, but because all the fengGUI widgets have a mouseEntered and mouseExited callback I just use it to set a boolean value in my control class. Then, during the update, I just check the value to see if it is the GUI or the game that is being manipulated.
How would one use the class GameControlManager properly. Is it okay to have one ControlManager per (logically coheisive) control set to be able to switch all controls off setwise? Or are there good reasons not to do that?
I don't use GameControlManager, sorry. Maybe I should take a look.
Yeah, you can have many GameControlManagers at any given time and turn one or several off/on to fit your needs. This is what I do in my game development and although I think there could be a better way to organize this in the future for simplicity I haven't thought of the better route yet…if someone does I'm up to making a change.
Okay, thanks. I have now refactored the project to make use of multiple GameControlManagers.
But there is still this focus-thing.
On pressing enter I activate the chat and want to get the focus in the JTextField, but no matter how I try to accomplish this (setFocusable, setRequestFocusEnabled, grabFocus, requestFocus, requestFocusInWindow), the the focus will not be granted to the JTextField.
Is there anything I am missing? Must I maybe change or call something on the JMEDesktopState or so?
Unfortunately I have still not figured it out. Has anybody ever managed to get the focus set (e.g. on pressing ENTER) to a Swing component (which is attached to the JDesktop of a JMEDesktopState)?
Does JMEDesktop.setFocusOwner work?
No, I haven't. It worked. Thanks a lot!