Rechenoperation mit Slider

Hallo,

ich habe hier einer Controller in dem ich über einen Slider und ein Textfield eine Birectionale Bindung hergestellt habe.

Das gleiche kann ich auch mit einem Label machen, nur eben einseitig, wobei mir der Wert des Sliders angezeigt wird.

Ist es möglich, ohne das ich einen Change Listener auf die Propertys registriere, um eine Rechenoperation mit dem Wert des Sliders und einem Wert X durchzuführen und dieses Ergebnis im Label ausgeben kann?


import java.net.URL;
import java.text.NumberFormat;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.control.TextField;

public class MainController implements Initializable {
	
	double wert = 1.20;

	@FXML
	Slider slider;

	@FXML
	TextField field;

	@FXML
	Label label;

	private static final double INIT_VALUE = 0;


	@Override
	public void initialize(URL location, ResourceBundle resources) {
		slider.setValue(INIT_VALUE);
		field.setText(new Double(INIT_VALUE).toString());
		field.textProperty().bindBidirectional(slider.valueProperty(), NumberFormat.getNumberInstance());

		label.setText(new Double(INIT_VALUE).toString());
		//label.textProperty().bindBidirectional(slider.valueProperty(), NumberFormat.getNumberInstance());



	}

}

Hmja. Das geht dann halt nicht „bidirectional“, aber…

  • slider.valueProperty() ist eine DoubleProperty
  • mit .add(123) bekommt man ein DoubleBinding
  • mit .asString() bekommt man ein StringBinding
    und das kann man an den Label-Text binden:
import java.text.NumberFormat;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import javafx.scene.layout.VBox;

public class LabelSliderBinding extends Application
{
    public static void main(String[] args)
    {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage)
    {

        double value = 12.34;

        Slider slider = new Slider();
        slider.setValue(value);

        TextField textField = new TextField();
        textField.setText(String.valueOf(value));
        textField.textProperty().bindBidirectional(
            slider.valueProperty(), NumberFormat.getNumberInstance());

        Label label = new Label();
        label.setText(String.valueOf(value));

        label.textProperty().bind(slider.valueProperty().add(123).asString());

        VBox root = new VBox();
        root.getChildren().add(slider);
        root.getChildren().add(textField);
        root.getChildren().add(label);
        primaryStage.setScene(new Scene(root, 300, 250));
        primaryStage.show();
    }
}

BTW: Bei leerem Text schmeißt das eine ParseException. Es MUSS eine elegantere Möglichkeit geben, das zu verhindern, als das krampfige

        textField.textProperty().bindBidirectional(
            slider.valueProperty(), new StringConverter<Number>()
            {
                NumberFormat format = NumberFormat.getNumberInstance();
                
                @Override
                public String toString(Number value)
                {
                    return format.format(value);
                }

                @Override
                public Number fromString(String value)
                {
                    try
                    {
                        return format.parse(value);
                    }
                    catch (ParseException e)
                    {
                        return 0.0;
                    }
                }
            });

was man in „nicht-FX-Java“ ( :smiley: ) machen würde…