2016-08-19 2 views
1

패널의 모든 컨트롤에 대한 변경 리스너를 추가하려고합니다. 강력하기 때문에 fxml 파일을 변경할 때마다 컨트롤의 변경 사항을 수신하는 코드를 변경하지 않아도됩니다.Javafx가 패널에서 제어 변경 사항을 수신 대기합니다.

특정 유형의 컨트롤에 대한 수신기를 추가하는 방법을 생각해 냈습니다.

panel.getChildren() 
    .stream() 
    .filter(node -> node instanceof TextField).forEach(node -> 
      ((TextField) node).textProperty() 
       .addListener((observable, oldValue, newValue) -> { 
         //execute some code 
       })); 

그러나이 기능을 사용하려면 패널에서 사용할 모든 유형의 컨트롤에 비슷한 코드를 추가해야합니다.

panel.getChildren() 
    .stream() 
    .filter(node -> node instanceof TextField).forEach(node -> 
      ((TextField) node).textProperty() 
       .addListener((observable, oldValue, newValue) -> { 
         //execute some code 
       })); 

panel.getChildren() 
    .stream() 
    .filter(node -> node instanceof TextArea).forEach(node -> 
      ((TextArea) node).textProperty() 
       .addListener((observable, oldValue, newValue) -> { 
         //execute some code 
       })); 

//and so on... 

panel.getChildren() 
    .stream() 
    .filter(node -> node instanceof ComboBox).forEach(node -> 
      ((ComboBox<?>) node).valueProperty() 
       .addListener((observable, oldValue, newValue) -> { 
         //execute some code 
       })); 

내가 원하는 것은.

컨트롤이있는 패널이있는 문서 편집기가있어서 사용자가 프리셋 값을 제어 할 때마다 저장 및 취소 버튼이있는 패널이 활성화됩니다. 또한 사용자가 문서를 취소하거나 저장하지 않고 프로그램을 종료하려고 시도하면 변경 사항을 취소하고 종료 또는 취소할지 묻는 경고 메시지가 나타납니다.

그러나 문서 구조를 많이 변경하려고하므로 패널에서 컨트롤을 추가하거나 제거해야합니다. 그래서 한 번에 패널의 모든 컨트롤에 대해이 유형의 리스너를 추가하는 가장 좋은 방법이 필요합니다.

+0

그것은 당신이 실제로 원하는 무엇 (이 작업을 수행하는 방법은 없습니다처럼 사용 예는 수 이러한 확장 된 텍스트 필드는 다음과 같이한다 해야 할 것). 당신이들을 수있는 모든 컨트롤에는 단일 한 속성이 없습니다. 예를 들어'TextField'는'textProperty'를 가지고 있고,'CheckBox'는'selectedProperty'를 가지고 있고,'ComboBox'는'valueProperty'를 가지고 있고,'전형적으로'textProperty'를 가지고있는'editor'도 있습니다; 'ListView'와'TableView'에는'selectedItem' 속성을 가진'selectionModel'이 있습니다. –

답변

2

자신의 컨트롤을 작성 (확장)하고 응용 프로그램에서 사용해야합니다. 그것들에서 @James_D가 언급 한대로 모든 특정 추적 로직을 구현할 수 있습니다.

public class TrackableTextField extends javafx.scene.control.TextField { 

    private StringProperty originalText = new ReadOnlyStringWrapper(this, "originalText"); 
    public final String getOriginalText() { return originalText.get(); } 
    public final void setOriginalText(String value) { 
     originalText.set(value); 
     setText(value); 
    } 
    public final StringProperty originalTextProperty() { return originalText; } 

    private final ReadOnlyBooleanWrapper dirty = new ReadOnlyBooleanWrapper(this, "dirty", false); 
    public final boolean isDirty() { return dirty.get(); } 
    public final ReadOnlyBooleanProperty dirtyProperty() { return dirty.getReadOnlyProperty(); } 

    public TrackableTextField() { 
     init(); 
    } 

    public TrackableTextField(String text) { 
     init(); 
     setOriginalText(text); 
    } 

    private void init() { 
     textProperty().addListener(e -> { 
      dirty.set(!Objects.equals(getOriginalText(), getText())); 
     }); 
    } 

    public void rollback() { 
     setText(getOriginalText()); 
    } 

    public void commit() { 
     setOriginalText(getText()); 
    } 
} 

을 내가 완전히 명확하지 않다하지만

public class Test extends Application { 

    private TrackableTextField tf_name = new TrackableTextField(); 
    private TrackableTextField tf_sname = new TrackableTextField(); 

    private Button save = new Button("Save"); 
    private Button discard = new Button("Discard"); 

    @Override 
    public void start(Stage primaryStage) { 

     GridPane root = new GridPane(); 

     root.add(new Label("Name: "), 0, 0); 
     root.add(tf_name, 1, 0); 

     root.add(new Label("Surname: "), 0, 1); 
     root.add(tf_sname, 1, 1); 

     root.add(save, 0, 2); 
     root.add(discard, 1, 2); 

     Scene scene = new Scene(root, 300, 250); 

     primaryStage.setScene(scene); 
     primaryStage.show(); 

     initialize(); 

    } 

    private void initialize() { 

     save.setDisable(true); 
     discard.setDisable(true); 

     save.disableProperty().bind(tf_name.dirtyProperty().or(tf_sname.dirtyProperty()).not()); 
     discard.disableProperty().bind(tf_name.dirtyProperty().or(tf_sname.dirtyProperty()).not()); 

     tf_name.setOriginalText("guleryuz"); 
     tf_sname.setOriginalText("guleryuz"); 

     save.setOnAction(e -> { 
      tf_name.commit(); 
      tf_sname.commit(); 
     }); 

     discard.setOnAction(e -> { 
      tf_name.rollback(); 
      tf_sname.rollback(); 
     }); 

    } 

    public static void main(String[] args) { 
     launch(args); 
    } 

} 
관련 문제