how to use javafx textfield maxlength

2019-04-09 03:16发布

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);
    }
}

5条回答
三岁会撩人
2楼-- · 2019-04-09 03:29

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?

查看更多
混吃等死
3楼-- · 2019-04-09 03:35

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楼-- · 2019-04-09 03:36

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楼-- · 2019-04-09 03:45

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)

查看更多
做自己的国王
6楼-- · 2019-04-09 03:47

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
            }

        });
查看更多
登录 后发表回答