I have seen questions about moving a cursor using the Robot class by an x and y coordinate, but I am trying to figure out how to reposition a cursor among text in a JTextField.
I have an open parenthesis button that when clicked will take whatever text might be in the JTextField already, concat "(" to it and set this to the JTextField.
I was wondering how I might add the closing parenthesis as well, BUT put the cursor in between the 2 so the user can keep typing uninterrupted. Any suggestions?
If you want to move the Caret in a JTextField to a specific location from a button then one way to do this would be to set focus upon it first using the JTextField.requestFocus() method then you would need to use the JTextField.setCaretPosition() method to actually relocate the Caret.
If you have a JTextField named jTextField1 and you want to move the Caret to the end of the text contained within then you can use:
jTextField1.requestFocus(); //
jTextField1.setCaretPosition(jTextField1.getText().length());
You need to be careful not to exceed the length of text within the JTextField otherwise an IllegalArgumentException will occur which you can catch by surrounding the above code within a try/catch block. You will also need to consider those times when there might not be any text within the JTextField.
try {
jTextField1.requestFocus();
jTextField1.setCaretPosition(jTextField1.getText().length());
}
catch (IllegalArgumentException ex) {
///Do Something Here...
}
To Append Brackets to the end of a JTextField then place the Caret between them would be something like this:
String txt = jTextField1.getText(); // Get the text contained in Textfield (if any)
if (txt.equals("")) { txt+= "()"; } // Nothing for text so just add Parenthases
else { txt+= " ()"; } // Some text there so add a space and Parenthases
jTextField1.setText(txt);
try {
// Set focus to JTextField
jTextField1.requestFocus();
// Move the caret between the Parenthases
jTextField1.setCaretPosition(jTextField1.getText().length()-1);
}
catch (IllegalArgumentException ex) {
// Do something here...
}
I have an open parenthesis button that when clicked will take whatever text might be in the JTextField already, concat "(" to it and set this to the JTextField.
Don't use getText()/setText() to do this.
Instead you just want to "append" the new text to the text field.
So the logic in your ActonListener might be something like:
int end = textField.getDocument.getLength();
textField.setCaretPosition(end);
textfield.replaceSelection("()");
textField.setCaretPosition(end + 1);
Appending text is more efficient because you only generate a DocumentEvent for the added text.
If you use the getText()/setText() approach then you generate a DocumentEvent for the remove text and then a second event for the text added, which does not reflect what actually happened.
Also, using the length from the Document instead of getting the text is also more efficient since you don't need to actually create a String object.
Related
How can I replace the selected text with something in android's edittext?
For example:
Default Text
Assume "Default" is selected now.
I want to replace it with !boldDefault.
How can I do it? I tried using get selection method but I couldn't replace it.
If the EditText currently has text selected, you can access the start and end points of the selection like so:
int start = editText.getSelectionStart();
int end = editText.getSelectionEnd();
You can access the EditText's Editable text like this:
Editable edit = et.getText();
Now you can replace anything inside that Editable using the replace() method:
String newText = "this will replace the current selection";
edit.replace(start, end, newText);
Once you've done that, you probably want to change the selection so that you don't have part of your new text still selected:
editText.setSelection(start + newText.length());
The problem is that when i click on the surname field when the name field is empty both messages appear because the focus is lost even from surname when the message dialog appears. Is there anything i can do to make the program show the name message and the focus to stay on the name field?
I tried the .requestFocus() but it didn't work.
private void NameFieldFocusLost(java.awt.event.FocusEvent evt) {
if (NameField.getText().equals('smth')) {
JOptionPane.showMessageDialog(null, "Please put a name!","Error!", JOptionPane.INFORMATION_MESSAGE);
}
}
private void SurnameFieldFocusLost(java.awt.event.FocusEvent evt) {
if (SurnameField.getText().equals("smth")) {
JOptionPane.showMessageDialog(null, "Please put a surname!","Error!", JOptionPane.INFORMATION_MESSAGE);
}
}
First off, in the NameFieldFocusLost event: if (NameField.getText().equals('smth')) { doesn't fly. The equals() method requires a String: if (NameField.getText().equals("smth")) { or better yet...since you want to ensure a name is actually provided:
if (NameField.getText().trim().equals("")) {
There must be something we're not being shown. I don't understand why both MessageBoxes would be displaying when focus is taken away from the nameFieldFocusLost event. This shouldn't happen unless you have code somewhere moving focus around especially before your form is actually visible. The requestFocus() method should work as well and should be called directly after you display the MessageBox, for example:
private void nameFieldFocusLost(java.awt.event.FocusEvent evt) {
if (nameField.getText().trim().equals("")) {
JOptionPane.showMessageDialog(this, "Please put a name!","Error!", JOptionPane.INFORMATION_MESSAGE);
nameField.setText(""); // Clear the JTextField in case a white-space was placed there.
nameField.requestFocus(); // Force focus back onto the JTextField.
}
}
If you are moving focus to a JTextField before the parent container is visible (Form / JDialog) then you could possibly experience your particular problem.
EDIT:
Ahhh...I see the problem, thank you for the comment. Here are a few ways you can get around this dilemma:
Add a condition within the focusLost event for the next
JTextField to be in focus which will force an exit of that event
should the validation of the previously focused JTextField fail.
In your case you have a First Name text field and a Last Name text
field. In the focusLost event for the Last Name field you would have
the very first line of code being:
if (nameField.getText().trim().equals("")) { return; }
This way the remaining event code doesn't get run in the Surname
Lost Focus event unless validation for Name field is successful. The
entire Surname event code may look like this:
private void surnameFocusLost(java.awt.event.FocusEvent evt) {
if (nameField.getText().trim().equals("")) { return; }
if (surnameField.getText().trim().equals("")) {
JOptionPane.showMessageDialog(this, "Please put a last name!","Error!", JOptionPane.INFORMATION_MESSAGE);
surnameField.setText(""); // Clear the JTextField in case a white-space was placed there.
surnameField.requestFocus(); // Force focus back onto the JTextField.
}
}
An other way would be to utilize the InputVerifier
Class.
There is good example of its use in this SO
post.
Don't use the JTextField's Focus Events at all. If there is a button
that will be selected to further processing with the inputted data
then check the validation for all your JTextFields there (in the button's actionPerformed event) and force a
focus upon the field that fails (nameField.requestFocus();) for proper input.
Here is my application. It's a wallet to update my money when I spend or get profit. Look it up on image hosting here http://tinypic.com/r/687bdk/8
Is there a way to detect that a cursor has been put into one of the JTextFields? If there is, then could I dispatch a method that would delete whatever is in the other JTextField? There should only be one JTextField with input, it is unacceptable to have inputs in both text fields.
You can add a FocusListener to each textfield i.e.
JTextField myTextField = new JTextField();
myTextField.addFocusListener(new FocusListener() {
#Override
public void focusGained(FocusEvent e) {
//when selected...
}
#Override
public void focusLost(FocusEvent e) {
//when not selected..
}
});
Is there a way to detect that a cursor has been put into one of the JTextfields? If there is, than I could dispatch a method that would delete whatever is in the other JTextField.
As a user I'm not too crazy about that design. I've used accounting type applications before where you have two columns (debit/credit) and a number can only be entered into one.
In those applications the number is not removed on focus, it is removed if a value is entered in the other field. This allows for tabbing between fields on the forum without data disappearing just because focus changes.
To implement this type of functionality you would add a DocumentListener to the Document of the text field. Then whenever text is entered into the Document the listener is invoked and you can clear the text from the other text field.
Check out the section from the Swing tutorial on How to Write a DocumentListener for more information and examples.
It called: CaretListener
jTextArea=new JTextArea();
jTextArea.addCaretListener(new CaretListener(){
public void caretUpdate(CaretEvent e){
//your code
}
}
);
It mainly used when you need to know that your caret position is changed.
First off I making a simple typing program. If you type the a letter and hit the spacebar the TTextArea will be matched with the label text to see if it matches. But it keeps coming out wrong cause there is space added before the letter after the first output everytime and I do not understand why? Is this something that just happens or can ypu
The is my code
public void keyTyped(KeyEvent e) {
if(e.getKeyChar() == KeyEvent.VK_SPACE){
input = textArea.getText();
if(input.length() <= 0){
JOptionPane.showMessageDialog(null, "Type something first");
} else {
input.trim();
System.out.println(input);
gameLogic.score(input, letterLabel.getText());
gameLogic.error(input, letterLabel.getText());
scoreLabel.setText("Score: " + String.valueOf(gameLogic.score));
errorLabel.setText("Errors: " + String.valueOf(gameLogic.error));
gameLogic.changeDifficulty();
letterLabel.setText( gameLogic.changeText());
textArea.setText("");
textArea.setCaretPosition(0);
}
}
this is my output
l
l
x
k
ss
Several things...
KeyListener is not a recommend way to deal with monitoring or effecting the changes to any text component. If you are lucky enough that the key stroke isn't consumed by the component, the component has already being updated with the last key stroke.
A better approach would be to use a DocumentListener if you just wanted to monitor changes to the text component or a DocumentFilter if you want to change what is being passed to the field.
Check out Using Text Components for more details
Using a JEditorPane, is there any way to tell if the caret is currently on the last line? I cannot find anything in the API or more importantly JTextComponent of which JEditorPane is derived. I need to find this out when the user uses the down arrow key to move down the text. My current idea is this:
private boolean isEndOfText() {
int tmpCurrent = editor.getCaretPosition();
editor.getActionMap().get(DefaultEditorKit.endLineAction).actionPerformed(null);
int tmpEnd = editor.getCaretPosition();
try { editor.setCaretPosition(tmpEnd + 1); } catch (Exception e) { editor.setCaretPosition(tmpCurrent); return true; }
editor.setCaretPosition(tmpCurrent);
return false;
}
This code would run whenever the down key is pressed and would return whether or not it is in fact the end of the text by detecting if an error occurs if the caret is being put after the last possible position which would be the end of the line (if it is in fact the last line) otherwise it means the end of text has not been reached.
You should be able to use the Text Utilities. One method returns the total lines and another method return the line at the caret.
I've never played with a JEditorPane that much since I don't like its HTML support. You might also be able to use editor.getDocument().getLength() to determine if the caret is at the end of the document. This will work with a JTextArea or a JTextPane that only displays text, not HTML. Not sure how it works in a JEditorPane.
There's probably a better way, but you could try this:
return editor.getText().indexOf("\n", editor.getCaretPosition()) == -1;