I am making my own text editor in JavaFX and I want to have bracket completion. Like in Netbuns. I have tried using a ChangeListener on the TextArea and checking if the last character is a bracket and append the char like this:
textArea.textProperty().addListener(new ChangeListener<String>()
{
#Override
public void changed(final ObservableValue<? extends String> observable, final String oldValue, final String newValue)
{
if (textArea.getText().charAt(textArea.getText().length()-1) == '{')
{
textArea.appendText("}");
}
}
});
But since it's only checking the last character in the textArea, this doesn't work for code where there are brackets inside brackets. Does anyone know a way to fix this? It may also be helpful to note that I am using JDK 1.7.0_55 and my school refuses to update to JDK 8. Any help will be appreciated.
You should use anchor property to receive position of caret instead of using text length value.
Related
So I have probably an easy question, but I couldn't find anyone asking this question on Google, so now I'm here.
The problem is simple - I must copy a line of text that has white spaces and tabulators in it, but once I copy it inside my text (input) field, it removes all the tabulators for some reason, so it leave the text all in one big mess that I cannot filter anything out of it.
Any ideas what could be done so those input fields would allow tabulators?
P.S. By pressing tab while I'm inside the input field, it moves between the buttons, instead of inputting a tabulator.
The content of a TextField is represented by a private static class TextFieldContent. TextFieldContent implements insert(int index, String text, boolean notifyListeners) method to filter the input text. The method uses a static method from TextInputControl class to remove "illegal" characters, here is the implementation:
#Override
public void insert(int index, String text, boolean notifyListeners) {
text = TextInputControl.filterInput(text, true, true);
if (!text.isEmpty()) {
characters.insert(index, text);
if (notifyListeners) {
ExpressionHelper.fireValueChangedEvent(helper);
}
}
}
The last parameter in TextInputControl.filterInput(text, true, true) defines whether tab characters are "illegal" or not. It's set to true and as I mentioned before, that class is a private static final class and you can't extend it and override insert method.
The solution is to extend TextInputControl and create a custom Content class that doesn't remove tab characters.
As an alternative, you can use TextArea, text areas accept tab characters.
I need to check user input in realtime. So when the user has entered more than for example 40 characters, he will be sent to the next line. I tried to use getText method in onKeyReleased method, but when the user hold the key, it can enter more than 40 characters. Sorry, maybe the explanation is not good enough.
Maybe what you are looking is something like that:
/* [Code...] */
#FXML
private void initialize() {
firstField.textProperty().addListener((observable, oldValue, newValue) -> {
if (newValue.length() > 40)
secondField.requestFocus();
});
}
/* [Code..] */
Need to do the changes on the Controller class.
As Sendrick suggested on the link this.
I want to add a special character to a textfield .
For example I want to add / automatically between a date that user typed.
Or adding some space between some digits in a number .like this: "2020 2020 2020 2020"
I used this code but it doesn't work correctly .
textfield.textProperty().addListener(new ChangeListener<String>(){
#Override
public void changed(ObservableValue<? extends String> ov, String t, String t1) {
if(t1.length()==4 || t1.length()==9 || t1.length()==14){
textfield.setText(t1+" ");
System.out.println("space added");
}
}
}
It's adding the space just fine. I think the issue is that you want to move the carat position after adding the extra text. You can use textfield.getCaratPosition() to find the current position and textfield.positionCarat(...) to change it.
The logic is going to be quite complex though and depends greatly on what the user is doing and precisely how you want the text field to behave. E.g. what if the text is changing because the user deletes something? What about copy and paste?
I have an SWT Text and i dont want any special characters to be entered , but only digits and numbers. So i have used the verify lister for the text :
text.addVerifyListener(new VerifyListener()
{
#Override
public void verifyText(VerifyEvent event)
{
char eachChar = (Character)event.character;
if(Character.isLetterOrDigit(eachChar))
{
event.doit = true;
}
else
{
event.doit = false;
}
}
});
So now i'll not be able to enter special characters.
1) How do i enable paste of a text inside the Text ?
2) And when i copy a text containing special characters from outside and paste it in the Text , it should not get pasted How do i restrict this ?
Please suggest me on this.
1) How do i enable paste of a text inside the Text ?
Paste will be enabled by default for SWT text. You no need to enable explicitly.
2) And when i copy a text containing special characters from outside and paste it in the Text , it should not get pasted How do i restrict this ?
"event.text" will give you the text you enter/paste to the SWT text. Validate this event.text with your regular expression (or with your isLetterOrDigit() by reading the event.text as character)
I am currently creating this java GUI that will ask the user to input 10 entries, then use the values to execte the next action.
I want only numbers or decimal point to be inputted inside such that it can only be a float value.
If it is not number or decimal point, it should prompt the user to input that specific entry again before the next action is executed.
How should I do it?
Wong,
not sure whether you are using Swing or not...
Ages ago I had the same problem and I solved it with creating a class RestrictedTextField extending JTextField. In the constructor I added a key listener (addKeyListener(new RestrictedKeyAdapter());)
private class RestrictedKeyAdapter extends KeyAdapter {
#Override
public void keyReleased(KeyEvent e) {
if (getText().equals("")) {
oldString = "";
return;
} else {
// if you cannot parse the string as an int, or float,
// then change the text to the text before (means: ignore
// the user input)
try {
if (type.equals("int")) {
int i = Integer.parseInt(getText());
oldString = getText();
} else if (type.equals("float")) {
float f = Float.parseFloat(getText());
oldString = getText();
} else {
// do nothing
}
} catch (NumberFormatException el) {
setText(oldString);
}
// if the text is identical to the initial text of this
// textfield paint it yellow. If the text was changed
// paint it red.
if (initialString.equals(getText())) {
setForeground(Color.YELLOW);
} else {
setForeground(Color.RED);
}
}
}
}
The idea is, that every time the user presses a key in the textfield (and releases it then), the text in the textfield is parsed. If the component should accept only floats for example then the component tries to parse it as an float (Float.parseFloat(..)). If this parsing is successful everything is fine. If the parsing fails (an NumberFormatException is thrown) then the old text is written back into the textfield (literally ignoring the user input).
I think you can add the KeyAdapter directly to the JTextField without creating a dedicated class for that, but with this solution you can remember the initial string and the old string.
you can play around with the code.. you can change the colour of the textfield if the input is valid or not (or like in my code snippet if the text is identical to the initial string).
one additional comment: I set the 'type' of the textfield in a variable with the name 'type', which is simply a String with the values "int", "float", etc.... a better solution would be here for example an enum of course...
I hope this is helpful...
timo
There are various options for what you would like to do. You can check here for one example of doing so. Another example could be to use Formatted TextFields, as shown here.
On the other hand, upon submission, you can try to parse the value to a float or double. If you get any exceptions, then, the value is not a number.
Lastly, you can use Regular Expressions. An expression such as ^\\d+(\\.\\d+)?$ should match any integer or floating point number.