I'm writing a program using JavaFX and I currently have three TextFields. When you press enter while any of the text fields are focused, there is an EventHandler which calls the appropriate method for each field. There is no submit button because I want it to submit each input separately (that's just how I made the rest of the program) to be validated and return a String containing any errors in the input. If the users input is invalid, it resets it to the last valid value it had.
However, when testing I found that sometimes I just click somewhere else (such as the next field) rather than pressing enter, so I wanted to implement the same function as pressing enter but when the user clicks outside the field. There is a MouseClicked event on the root that I have attempted to make it submit the input for all of the fields at once which works, but if any field has not been filled in, then it will be unsuccessful and return an error message (which might confuse a user).
Additionally, if the user clicks inside the TextField again, say to delete something from the middle of the word, the event will be triggered and the field will be reset to the last valid value if the current input was invalid.
I've considered using a MouseExited event on each field, but I think that might be triggered by the cursor leaving the field, rather than a click outside of the field.
What would be a good way of doing this, while minimising the number of event methods in my program?
Related
I'm currently working on the input system of a game engine in java, and I use GLFW for the window. I set up a callback system to catch when a key is pressed:
GLFW.glfwSetKeyCallback(window, (windowId, key, scancode, action, mods) -> {
if (action == GLFW.GLFW_PRESS) {
System.out.println(GLFW.glfwGetKeyName(key, scancode));
}
});
And the problem is when I press space or enter or shift plus a different key it prints out null. My question is: how to use the mods attribute to capitalize the next key when I press shift or print out a new line when I press enter etc.
I don't know the solution for the first question, but the second one is easy.
Try using char callback. This one is different from key callback, as it only works with unicode characters being typed by user (letters are capitalized with Shift, CapsLock button also works). Also, if you want to detect modifier buttons being pressed while user types, try using charMods callback. Seems like the latter is marked for removal, so you can test whether the modifier button is pressed with glfwGetKey().
EDIT: Seems like I didn't understood you on the first one. glfwGetKeyName() is not designed to be used as text input method. Also note that it can display names for a limited range of buttons. What is more, when you press multiple keys, press event for each one is called in separate key callback event. You can't handle multiple key presses at once. (Modifier keys are put in mods argument of callback, but I can't tell by now whether they also trigger a key press event or not - check it yourself)
I know there are many questions on how to focus on a certain text field and so on, but it seems that the issue I am facing is a bit different. So, I have a JTextField which has functionality to autocomplete the text if something that is currently in it has been typed before by the user. I also have a set of buttons that perform insertion of some predefined portion of text into the text field when pressed. The problem is that every time any new text appears in the text field, the autocomplete can trigger and append the text that was used by the user previously. In order to it more friendly, I decided to select the part appended by the autocomplete. All the code is executed in the ED thread. Consider the case when the text field was not in focus :
Both code samples are in the actionPerformed method of the button.
// does not work
if (textField.requestFocusInWindow()) {
textField.getDocument().insertString(...);
}
The insertString() is overriden and has all the logic to select appended string by the autocomplete. So, the only thing I need is that the text field is selected before the string is inserted.
I tried :
// does work
textField.requestFocusInWindow();
SwingUtilities.invokeLater(() -> {
textField.getDocument().insertString(...);
});
The official doc says :
The call to the requestFocusInWindow method initiates the focus transfer, but it does not immediately move the focus ...
This sort of makes sense, since to acquire the focus, a call must be made to the window manager of the clients operating system (that's how I understand that, correct me if I am wrong).
Is the second example working mainly because both events (getting focus and inserting the string) are added to the event queue and the insertion appears after the focus request (actually at the end of the queue) or am I missing something? Is it a valid solution? Can it be done better?
Note: simply adding a listener to the text field ( to react when it is in focus) is not a solution, since the logic I described here is only a part of the whole functionality used.
I have an SWT Text and I want it to have Focus until the User Enters something.
Currently I´m using a FocusListener and check at focusLost Event, if the User has entered something. If not, I throw him back to the Text Field.
I think this is the wrong way as I don´t want anything to happen which I have to reverse then (e.g. if the user focuses another Part, I have to give focus back to the part with the Text and so on)
Does SWT provide me a way of blocking any other action but entering something into the SWT Text?
Like a Listener that gets triggered before the action happens and in which I can prevent the action to happen? Like a VerifyListener for every event type?
In my Swing app, I have a screen that has a bunch of JTextFields. Each JTextField uses an ActionListener's actionPerformed method to copy the user-entered text to my data model object.
This method seems to only be called if the user presses Enter. How can I copy the user-entered text to my data model object if the user doesn't press Enter but instead 1) tabs between fields or 2) uses the mouse to click from one field to the next?
If you only want to perform an action when the user moves away from the field (not on every character changing in the field) then listen to the focus events:
JTextField textField = ...
textField.addFocusListener(new FocusAdapter(){ void focusLost(FocusEvent e)
{ doSomething(); } );
You might want to take a look at JFormattedTextField which handles this kind of thing for you.
muJTextField.addFocusListener(/* focus listener here */); for focus changes
myJTextField.getDocument().addDocumentListener(/* document listener here */); for document changes
For document changes use changeUpdate()
the problem with mouseclick, is that the component you click on must grab focus, else focus lost will not be called...
i had the same problem, so i used a timer to commit my code, every x milliseconds...if you sure that focus lost will be called when you click on some other component, a simple focus listener will do the trick...
In my application I have a JTextField that will only allow the user to fill it with input formatted in a certain way. I have a method that checks if input into the field is valid and if not it displays a dialog. After this occurs I would like the focus to return to the text field so that the user can correct there mistake and type in the appropriately formatted input. I tried to do this by having the JTextField call requestFocus() on itself but this seems to only half work. The JTextField displays the flashing cursor but I cannot actually type in any text until I click on the text field again. Is there another method I need to call? I could not find anything else in the documentation.
It's not exactly the solution you asked for, but you might want to look at javax.swing.InputVerifier. This object allows you to verify the input to a field and prevent taking focus away from it if the format isn't right. I don't think it would allow you to put up a dialog explaining the error (though it might - try it) but it would certainly allow you to put a message in a 'message area'.
What you do is set an InputVerifier on the JComponent, have it test the contents for validity; if it isn't right then the JComponent won't release focus (and can write an error message).