2016-07-15 3 views
1

JavaFX 프로젝트에서 작업 중이고 TextField 컨트롤을 사용하는 데 문제가 있습니다. 사용자가 각 TextField에 입력 할 문자를 하나로 제한하려고합니다. 당신이 리스너와 함께 하나의 텍스트 필드를 사용하는 경우 나는 해결책을 발견 :JavaFX TextField 배열 텍스트 길이의 최대 길이

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

    } 

내가 용액으로 사용했을

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

(!) 참고 : 나는 만든 공공 정적을 그래서 나는 그것을 GamePresenter에서 사용할 수 있습니다. 나는 Java에 매우 익숙하다.

미리 감사드립니다.

+1

는 언급 된 배열의 TextField '[]'과 tfArray' addTextLimiter'가 Main''로 구현되는 것을 가정 1)); ' – DVarga

+0

@DVarga의 솔루션은 TextField에 덮어 쓸 수있는 기본 리스너가 없기 때문에 가장 간단합니다. 리스너 목록은 기본적으로 비어 있습니다. – Westranger

+0

@Dvarga 귀하의 솔루션을 사용했지만 NullPointerException이 발생하고 이유가 없습니다 ... – CaptainAaargh

답변

2

이것은 GridPane이없는 해결책이지만 GridPane에도 Fields를 추가하는 쉬운 프로세스입니다. 그리고 훨씬 더 나은 TextFormatter가 있습니다. > Main.addTextLimiter (TF - `Arrays.asList (tfArray) .forEach (TF :

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

바운드 프로퍼티가 변경되기 전에 (사실 TextField의'text' 속성에 적용되기 전에) 변경 사항을 캐치 할 수 있으므로'TextFormatter'를 사용하는 것이 일반적으로 더 좋습니다 (8u60 이상). – Itai

+0

Nice, but ... 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