2016-08-19 8 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', а также' editor', который (как правило) имеет 'textProperty'; 'ListView' и 'TableView' имеют 'selectionModel', которые имеют свойство 'selectedItem' и т. Д. И т. Д. –

ответ

2

вы должны написать (расширить) свои собственные элементы управления и использовать их в своем приложении. В них вы можете реализовать всю специфическую логику отслеживания, как упомянуто @James_D. Такой расширенный TextField должен выглядеть следующим образом:

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

} 

 Смежные вопросы

  • Нет связанных вопросов^_^