Bindings

Veröffentlicht von

Hier mal ein paar Beispiele, wie man die JavaFX-Bindings einsetzen kann.

Einen Button deaktivieren, wenn ein Textfeld oder eine ComboBox leer ist
btn.disableProperty().bind(
    Bindings.isEmpty(textField1.textProperty())
    .and(Bindings.isEmpty(textField2.textProperty()))
    .and(Bindings.isEmpty(textField3.textProperty()))
    .and(comboBoxPersistent.valueProperty().isNull())
);Code-Sprache: CSS (css)
Einen Button deaktivieren, wenn ein ImageView null ist
btn.disableProperty().bind(Bindings.isNull(imageView.imageProperty()));Code-Sprache: CSS (css)
Ein bindBidirectional(), zwischen einem StringProperty und IntegerProperty
TextField textFieldAge = new TextField();
textFieldAge.textProperty().bindBidirectional(item.ageProperty(), new NumberStringConverter());  Code-Sprache: JavaScript (javascript)
List Size BooleanBinding
BooleanBinding isListEmpty = Bindings.createBooleanBinding(() -> menu.getItems().size() == 0, menu.getItems());
// oder
BooleanBinding isListInRange = Bindings.createBooleanBinding(() -> 
    menu.getItems().size() >= 10 && menu.getItems().size() <= 20, menu.getItems());Code-Sprache: JavaScript (javascript)
Text von einem Label aktualisieren

In dem Beispiel werden die Nodes in einem TreeView gezählt und per Binding an das Label übergeben.

labelCount.textProperty().bind(Bindings.format("Count: %s", countBinding));Code-Sprache: CSS (css)
private final IntegerBinding countBinding = new IntegerBinding() {
    @Override
    protected int computeValue() {
        // Beachten Sie, dass die AtomicInteger hier nur als veränderbarer Wrapper verwendet wird.
        // Die Atomizität ist uns egal, da sie nur von aktualisiert wird
        // ein Thread
        return countNodes(treeView.getRoot(), new AtomicInteger());
    }

    private int countNodes(TreeItem<?> node, AtomicInteger count) {
        count.incrementAndGet();
        for (TreeItem<?> child : node.getChildren()) {
            countNodes(child, count);
        }
        return count.intValue();
    }
};Code-Sprache: PHP (php)

Hier werden die Items in einem ListView gezählt und per Binding an das Label übergeben.

ListView<String> listView = new ListView();
ObservableList<String> items = FXCollections.observableArrayList();	

SimpleListProperty<String> listProperty = new SimpleListProperty<>(items);
labelCount.textProperty().bind(
			Bindings.format("Anzahl Items: %s", listProperty.sizeProperty()));
		
listView.setItems(listProperty.get());Code-Sprache: JavaScript (javascript)

Hier werden die Items in einem TableView gezählt und per Binding an das Label übergeben.
Diesen Code erst einfügen, nachdem die Items vom TableView gesetzt wurden, sonst geht es nicht.

labelCount.textProperty().bind(Bindings.format("Anzahl Items: %s", Bindings.size(tableView.getItems())));Code-Sprache: CSS (css)
Starte Action, wenn alle Bedingungen in einer Liste, erfüllt sind

Hier etwas Code, wie man z.B. eine Liste mit Checkboxen binden und kontrollieren kann, ob alle Checkboxen Selected sind.
– wenn alle Checkboxen „select = true“, dann gibt der Listener „sindJetztAlleSelected = true“ zurück
– wenn eine Checkbox „select = false“ ist, dann gibt der Listener „sindJetztAlleSelected = false“ zurück
ausführliches Beispiel

ACHTUNG: Die Variable „BooleanBinding allSelectedBikes“ muss eine globale Variable sein, mit einer lokalen Variable reagiert das Binding nicht.

private void bindPanelToPackages2(CheckBox pane, ObservableList<CheckBox> packages) {
	// BooleanBinding ist true, wenn alle CheckBoxen Selected sind 
	allSelectedBikes = Bindings.createBooleanBinding(() -> 
            packages.stream().allMatch(CheckBox::isSelected), 
            packages.stream().map(CheckBox::selectedProperty).toArray(Observable[]::new));

	// Wird nur true, wenn alle CheckBoxen Selected sind  
	allSelectedBikes.addListener((obs, oldVal, newVal) -> {
    	    pane.setSelected(newVal);
        });

	// Select alle CheckBoxen
        pane.setOnAction(e -> 
    	    packages.stream().forEach(box -> box.setSelected(pane.isSelected())));
}Code-Sprache: PHP (php)

Oder wenn eine bestimmte Anzahl von CheckBoxen selected sind.

private void bindPanelToPackages(CheckBox pane, CheckBox... packages) {
        allSelectedBikes = Bindings.createBooleanBinding(() -> 
        Stream.of(packages).filter(CheckBox::isSelected).count() > 3,
        Stream.of(packages).map(CheckBox::selectedProperty).toArray(Observable[]::new));
        
        // Wird nur true, wenn mehr als 3 CheckBoxen Selected sind 
        allSelected.addListener((obs, oldVal, newVal) -> 
            pane.setSelected(newVal));

        // Select alle CheckBoxen
        pane.setOnAction(e -> 
            Stream.of(packages).forEach(box -> box.setSelected(pane.isSelected())));
    }Code-Sprache: PHP (php)

Ausführliche Beispiele


Starte Action, wenn alle Bedingungen in einer Liste, erfüllt sind
  • wenn alle MenuItems im Menu „menuVehicles“ visible = false sind, dann wird das Menu „menuVehicles“ auf disable gesetzt.
  • wenn die CheckBox „selectAllCars“ selected ist, wird das MenuItem „menuItemCars“ auf visible = false gesetzt
  • wenn die CheckBox „selectAllBikes“ selected ist, wird das MenuItem „menuItemBikes“ auf visible = false gesetzt
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import javafx.application.Application;
import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class MultipleCheckBoxSelection extends Application {
	
    private BooleanBinding allSelectedCars;
    private BooleanBinding allSelectedBikes;
    private BooleanBinding allNotVisible;
    
    private Menu menuVehicles;

    private int numBoxes = 5;

    @Override
    public void start(Stage primaryStage) {
    	
    	MenuBar menuBar = new MenuBar();
    	
    	menuVehicles = new Menu("vehicles");
    	
    	MenuItem menuItemCars = new MenuItem("Cars");
    	MenuItem menuItemBikes = new MenuItem("Bikes");
    	
    	menuVehicles.getItems().addAll(menuItemCars, menuItemBikes);
    	menuBar.getMenus().addAll(menuVehicles);
    	   	
        CheckBox selectAllCars = new CheckBox("Select all Cars & set MenuItem Cars Visible false");
        selectAllCars.setStyle("-fx-padding: 20 0 10 10;");
        selectAllCars.selectedProperty().addListener(e -> {
        	menuItemCars.setVisible(!menuItemCars.isVisible());
        });
        
        CheckBox selectAllBikes = new CheckBox("Select all Bikes & set MenuItem Bikes Visible false");
        selectAllBikes.setStyle("-fx-padding: 10 0 10 10;");
        selectAllBikes.selectedProperty().addListener(e -> {
		menuItemBikes.setVisible(!menuItemBikes.isVisible());
        });
                      
        CheckBox[] boxesCars = IntStream
                .rangeClosed(1,  numBoxes)
                .mapToObj(i -> new CheckBox("Car "+i))
                .toArray(CheckBox[]::new);

        ObservableList<CheckBox> boxesBikes = IntStream
                .rangeClosed(1,  numBoxes)
                .mapToObj(i -> new CheckBox("Bikes "+i))
                .collect(Collectors.toCollection(FXCollections::observableArrayList));

        bindPanelToPackages(selectAllCars, boxesCars);
        bindPanelToPackages2(selectAllBikes, boxesBikes);
        bindPanelToPackages3(menuVehicles.getItems());
        
        VBox root = new VBox(menuBar);
        
        root.getChildren().add(selectAllCars);
        Stream.of(boxesCars).forEach(box -> box.setStyle("-fx-padding: 0 0 10 20;"));
        Stream.of(boxesCars).forEach(root.getChildren()::add);

        root.getChildren().add(selectAllBikes);
        boxesBikes.stream().forEach(box -> box.setStyle("-fx-padding: 0 0 10 20;"));
        boxesBikes.stream().forEach(root.getChildren()::add);

        Scene scene = new Scene(root, 350, 450);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private void bindPanelToPackages(CheckBox pane, CheckBox... packages) {

        // BooleanBinding ist true, wenn alle CheckBoxen Selected sind 
    	allSelectedCars = Bindings.createBooleanBinding(() -> 
            Stream.of(packages).allMatch(CheckBox::isSelected), 
            Stream.of(packages).map(CheckBox::selectedProperty).toArray(Observable[]::new));

        // Wird nur ausgeführt, wenn alle CheckBoxen Selected sind  
    	allSelectedCars.addListener((obs, wereAllSelected, areAllNowSelected) -> {
            System.err.println("all selected Cars");
            System.err.println("\twaren alle Selected: " + wereAllSelected);
            System.err.println("\tsind jetzt alle Selected: " + areAllNowSelected);
            pane.setSelected(areAllNowSelected);
        });

        // Select alle CheckBoxen
        pane.setOnAction(e -> 
            Stream.of(packages).forEach(box -> box.setSelected(pane.isSelected())));
    }

    private void bindPanelToPackages2(CheckBox pane, ObservableList<CheckBox> packages) {
	
	// BooleanBinding ist true, wenn alle CheckBoxen Selected sind 
	allSelectedBikes = Bindings.createBooleanBinding(() -> 
	    packages.stream().allMatch(CheckBox::isSelected), 
	    packages.stream().map(CheckBox::selectedProperty).toArray(Observable[]::new));
	
	// Wird nur ausgeführt, wenn alle CheckBoxen Selected sind  
	allSelectedBikes.addListener((obs, wereAllSelected, areAllNowSelected) -> {
	    System.err.println("all selected Bikes");
            System.err.println("\twaren alle Selected: " + wereAllSelected);
            System.err.println("\tsind jetzt alle Selected: " + areAllNowSelected);
	    pane.setSelected(areAllNowSelected);
	});
	
	// Select alle CheckBoxen
	pane.setOnAction(e -> 
	    packages.stream().forEach(box -> box.setSelected(pane.isSelected())));
    }
    
    private void bindPanelToPackages3(ObservableList<MenuItem> packages) {

    	// BooleanBinding ist true, wenn alle CheckBoxen Selected sind 
    	allNotVisible = Bindings.createBooleanBinding(() -> 
            packages.stream().allMatch(x -> !x.isVisible()), 
            packages.stream().map(MenuItem::visibleProperty).toArray(Observable[]::new));

    	menuVehicles.disableProperty().bind(allNotVisible);
    	
    	// Wird nur ausgeführt, wenn alle CheckBoxen Selected sind  
        allNotVisible.addListener((obs, wereAllNotSelected, areAllNotVisible) -> {
            System.err.println("all not Visible");
            System.err.println("\twaren alle Sichtbar: " + wereAllNotSelected);
            System.err.println("\tsind jetzt alle Sichtbar: " + areAllNotVisible);
        });
    }
    
    public static void main(String[] args) {
        launch(args);
    }
}Code-Sprache: PHP (php)