可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
How use this code in my main class of javafx.
So that I can set maxlength of characters in javafx texfield.
class LimitedTextField extends TextField {
private final int limit;
public LimitedTextField(int limit) {
this.limit = limit;
}
@Override
public void replaceText(int start, int end, String text) {
super.replaceText(start, end, text);
verify();
}
@Override
public void replaceSelection(String text) {
super.replaceSelection(text);
verify();
}
private void verify() {
if (getText().length() > limit) {
setText(getText().substring(0, limit));
}
}
};
My java fx main class is given below
public class TextFiled extends Application {
@Override
public void start(Stage primaryStage) {
final TextField t_fname = new TextField();
StackPane root = new StackPane();
root.getChildren().add(t_fname);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
回答1:
This is my solution:
public static void addTextLimiter(final TextField tf, final int maxLength) {
tf.textProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(final ObservableValue<? extends String> ov, final String oldValue, final String newValue) {
if (tf.getText().length() > maxLength) {
String s = tf.getText().substring(0, maxLength);
tf.setText(s);
}
}
});
}
See JavaFX 2.2 TextField maxlength and Prefer composition over inheritance?
回答2:
While the OP's technical problem is correctly answered (though not accepted), the solution to the base issue - how to restrict/validate input in a TextField which is answered in the other posts - has changed over time.
With java8u40 we got a new class TextFormatter: one of its main responsibilities is to provide a hook into any change of text input before it gets comitted to the content. To fulfill the requirement of limiting the input to a certain length (and - just for fun - show a context menu with an error message) we would
- implement a UnaryOperator that analyses all changes
- reject those which would result into a longer text (and show the message)
- accept all other changes
- instantiate a TextFormatter with the operator
- configure the TextField with the TextFormatter
A code snippet:
int len = 20;
TextField field = new TextField("max chars: " + len );
// here we reject any change which exceeds the length
UnaryOperator<Change> rejectChange = c -> {
// check if the change might effect the validating predicate
if (c.isContentChange()) {
// check if change is valid
if (c.getControlNewText().length() > len) {
// invalid change
// sugar: show a context menu with error message
final ContextMenu menu = new ContextMenu();
menu.getItems().add(new MenuItem("This field takes\n"+len+" characters only."));
menu.show(c.getControl(), Side.BOTTOM, 0, 0);
// return null to reject the change
return null;
}
}
// valid change: accept the change by returning it
return c;
};
field.setTextFormatter(new TextFormatter(rejectChange));
Aside:
Modifying the state of a sender while it is notifying its listeners about a change of that state is generally a bad idea and might easily lead to unexpected and hard-to-track side-effects (I suspect - though don't know - that the undo bug mentioned in other answers is such a side-effect)
回答3:
You should use your LimitedTextField
instead of TextField
.
Replace this line:
final TextField t_fname = new TextField();
with this one:
final LimitedTextField t_fname = new LimitedTextField(maxLength);
回答4:
This is very similar to LimitedTextField, but I feel it is more neat, because the verification is done before the textinput (and not afterwards). Also with the beep and hint the user gets some feedback, that the input was limited on purpose. The hint closes when the field looses focus.
import java.awt.Toolkit;
import javafx.scene.control.TextField;
public class DataTextField extends TextField
{
int length;
int compare;
public DatenTextField(int length)
{
super();
this.length = length;
}
public void replaceText(int start, int end, String text)
{
compare = getText().length() - (end - start) + text.length();
if( compare <= length || start != end)
{
super.replaceText( start, end, text );
}
else
{
Toolkit.getDefaultToolkit().beep();
show();
}
}
public void replaceSelection(String text)
{
compare = getText().length() + text.length();
if( compare <= length )
{
super.replaceSelection( text );
}
else
{
Toolkit.getDefaultToolkit().beep();
show();
}
}
private void show()
{
final ContextMenu menu = new ContextMenu();
menu.getItems().add(new MenuItem("This field takes\n"+length+" characters only."));
menu.show(this, Side.BOTTOM, 0, 0);
}
}
回答5:
My solution to limit a TextField
with a max length of characters:
final int maxLength = 20;
textField.setOnKeyTyped(t -> {
if (textField.getText().length() > maxLength) {
int pos = textField.getCaretPosition();
textField.setText(textField.getText(0, maxLength));
textField.positionCaret(pos); //To reposition caret since setText sets it at the beginning by default
}
});