2016-07-15 11 views
1

私はJavaFXプロジェクトで作業していますが、TextFieldコントロールを使用する際に問題があります。ユーザーが各TextFieldに入力する文字を1つに制限したい。リスナーで1つのテキストフィールドを使用すると解決策が見つかりました:JavaFX TextField Arrayテキストの長さの最大長

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

しかし、問題は私がTextFieldの配列を持っているということです。 TextFieldArrayのためにこのリスナーをどのように書き直すことができるか知っていますか?

配列リストの実装:アレイの

static public TextField[] tfLetters = new TextField[37]; 

初期化:

private void layoutNodes() { 
    int letternummer = 0; 
    for (int i = 1; i < 8; i++) { 
     for (int j = 0; j < i + 1; j++) { 
      this.tfLetters[letternummer] = new TextField("Letter " + i); 
      this.add(tfLetters[letternummer], j, i); 
      tfLetters[letternummer].setPadding(new Insets(5, 30, 5, 5)); 
      tfLetters[letternummer].setAlignment(Pos.CENTER); 
      tfLetters[letternummer].setMinSize(10, 10); 
      letternummer++; 
     } 

    } 

Iは、与えられた溶液を使用した:

Arrays.asList(tfLetters).forEach(tfLetters -> GamePresenter.addTextLimiter(tfLetters,1)); 

GamePresenterどこリスナービューのプレゼンタであります書かれた。 "GameView"ビューでは、テキストフィールドの配列を実装しました。私は与えられた解決策を実行したときしかし、今、私は次のNullPointerExceptionを行く:

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException 
at be.kdg.letterpyramide.view.GameView.GamePresenter.addTextLimiter(GamePresenter.java:36) 
at be.kdg.letterpyramide.view.GameView.GameView.lambda$layoutNodes$0(GameView.java:52) 
at java.util.Arrays$ArrayList.forEach(Arrays.java:3880) 

GameViewライン:36

tf.textProperty().addListener(new ChangeListener<String>() { 

GameViewライン:52

Arrays.asList(tfLetters).forEach(tfLetters -> GamePresenter.addTextLimiter(tfLetters,1)); 

は追記:私はそれのpublic static作ら私はそれを私のGamePresenterで使うことができます。私はJavaにとって非常に新しいです。

ありがとうございます!

+1

1)); ' – DVarga

+0

@DVargaの解決策は、TextFieldにはデフォルトのリスナーがないため、リスナーのリストはデフォルトでは空ですので、私の意見では最も簡単です。 – Westranger

+0

@Dvarga私はあなたのソリューションを使用しましたが、NullPointerExceptionが発生しました。理由はありません。 – CaptainAaargh

答えて

2

これはGridPaneのないソリューションですが、これはGridPaneにもフィールドを追加する簡単なプロセスです。そして今よりはるかに優れたTextFormatterを使用しています。 > Main.addTextLimiter(TF、 - 'は、Arrays.asList(tfArray).forEach(TF:あなたが言及した配列が `テキストフィールド[] tfArray`と` addTextLimiter`が `Main`に実装されていると仮定すると

import java.util.ArrayList; 
import java.util.List; 
import java.util.function.UnaryOperator; 
import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.scene.control.TextField; 
import javafx.scene.control.TextFormatter; 
import javafx.scene.layout.VBox; 
import javafx.stage.Stage; 

public class ChangeListenerDemo extends Application { 

    @Override 
    public void start(Stage primaryStage) { 
    List<TextField> fields = createLimitedTextFields(9, 1); 

    VBox box = new VBox(); 
    box.getChildren().addAll(fields); 

    Scene scene = new Scene(box, 300, 250); 
    primaryStage.setScene(scene); 
    primaryStage.show(); 
    } 

    private List<TextField> createLimitedTextFields(int num, int maxLength) { 
    final List<TextField> fields = new ArrayList<>(); 

    final UnaryOperator<TextFormatter.Change> filter 
      = (TextFormatter.Change change) -> { 
     if (change.getControlNewText().length() > maxLength) { 
      return null; 
     } 
     return change; 
    }; 
    for (int i = 0; i < num; i++) { 
     final TextField tf = new TextField(); 
     tf.setTextFormatter(new TextFormatter(filter)); 
     fields.add(tf); 
    } 
    return fields; 
    } 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 
    launch(args); 
    } 
} 
+1

'TextFormatter'を使うのが普通です(8u60以上の場合)。バインドされたプロパティが変更される前に変更をキャッチすることができます(実際には' TextField'の 'text'プロパティに適用される前に) – Itai

+0

ニース、しかし...あなたは 'getCaretPosition'は正確ですか?真ん中に何かを貼り付けるとどうなりますか? (最大長は10、テキストは "123456789"、 "1"の後に "abcdef"を貼り付けます。キャレットの位置は<10ですが、全長は> 10)です。私は 'getControlNewText()。length()'を使用するのが最も安全で、おそらく最も単純です。 – Itai

+0

@sillyfly ... 8u60以上? ['TextFormatter.Change'](https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/TextFormatter.Change.html)は8u40以降有効です。しかし、これは豆の数え方の一種です... – NwDev