簡體   English   中英

如何使用 JavaFX TextField maxlength

[英]How to use JavaFX TextField maxlength

如何在我的 JavaFX 主類中使用此代碼,以便我可以在 JavaFX TextField設置字符的最大長度?

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

    }
};

我的 JavaFX 主類如下:

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

雖然 OP 的技術問題得到了正確回答(盡管未被接受),但基本問題的解決方案 - 如何限制/驗證在其他帖子中回答的 TextField 中的輸入 - 隨着時間的推移發生了變化。

使用 java8u40,我們獲得了一個新類 TextFormatter:它的主要職責之一是在文本輸入被提交到內容之前提供一個鈎子到文本輸入的任何更改。 為了滿足將輸入限制為特定長度的要求(並且 - 只是為了好玩 - 顯示帶有錯誤消息的上下文菜單),我們將

  • 實現一個分析所有變化的 UnaryOperator
  • 拒絕那些會導致更長文本的內容(並顯示消息)
  • 接受所有其他更改
  • 使用運算符實例化 TextFormatter
  • 使用 TextFormatter 配置 TextField

一個代碼片段:

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

在旁邊:

修改發送者的狀態,同時通知其聽眾該狀態的變化通常是一個壞主意,並且可能很容易導致意想不到且難以跟蹤的副作用(我懷疑 - 雖然不知道 -其他答案中提到的撤消錯誤就是這樣的副作用)

這是我的解決方案:

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

請參閱JavaFX 2.2 TextField maxlengthPrefer composition over繼承?

您應該使用LimitedTextField而不是TextField

替換這一行:

final TextField t_fname = new TextField();

有了這個:

final LimitedTextField t_fname = new LimitedTextField(maxLength);

這個和LimitedTextField很像,但是我覺得更簡潔,因為驗證是在textinput之前完成的(而不是之后)。 此外,通過嗶嗶聲和提示,用戶會得到一些反饋,即輸入是有意限制的。 當字段失去焦點時,提示關閉。

import java.awt.Toolkit;
import javafx.scene.control.TextField;

public class DataTextField extends TextField
{
int length;
int compare;

public DataTextField(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);
}
}

我限制具有最大字符長度的TextField解決方案:

        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
            }

        });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM