Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Low Level binding in javafx(using computeValue)

Tags:

java

javafx

I am beginner in javafx. I want to bind a vertical slider to a rectangle height. I want to use low level binding.But it doesn't do anything. Please help me . Thank's

   rect = (Rectangle) root.lookup("#rect");
   vSlider = (Slider) root.lookup("#vSlider");
     final RectangleProperty rectangle = new RectangleProperty(rect);

   DoubleBinding vSliderBind = new DoubleBinding() {
         {
             super.bind(vSlider.valueProperty(),rectangle.heightpProperty());
         }

        @Override
        protected double computeValue() {
            rectangle.setHeightp(vSlider.valueProperty().doubleValue()*3);
           // System.out.print("vslider");
            return rectangle.getHeightp() ;
        }
    };
   vSliderBind.get()
like image 670
faraa Avatar asked Dec 30 '25 14:12

faraa


1 Answers

Why are you trying to use low level binding for this? The essence of the low level binding (as you say it) is to perform complex calculations, that are not possible with the fluent API. For binding height to the value of the slider, a simple line is sufficient:

r.heightProperty().bind(slider.valueProperty());

Even if you wanted simple manipulations (e.g. multiply it by something, be it a constant or another property):

r.heightProperty().bind(slider.valueProperty().multiply(0.5));

The following is a full code listing that will do the job:

import javafx.application.Application;
import javafx.geometry.Orientation;
import javafx.scene.Scene;
import javafx.scene.control.Slider;
import javafx.scene.layout.AnchorPane;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class RectHeightSlider extends Application
{
    @Override
    public void start(Stage primaryStage) {
        AnchorPane root = new AnchorPane();

        Slider slider = new Slider();
        slider.setMin(10);
        slider.setMax(100);
        slider.setValue(50);
        slider.setOrientation(Orientation.VERTICAL);

        root.getChildren().add(slider);

        Rectangle r = new Rectangle();
        r.setWidth(100);
        r.heightProperty().bind(slider.valueProperty());
        root.getChildren().add(r);
        AnchorPane.setRightAnchor(r, 0.0);

        primaryStage.setScene(new Scene(root, 300, 250));
        primaryStage.show();
    }

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

EDIT

If you have to do it low-level then do something like:

DoubleBinding vSliderBind = new DoubleBinding() {
    {
        super.bind(vSlider.valueProperty());
    }

    @Override
    protected double computeValue() {
        return vSlider.getValue();
    }
};

rectangle.heightProperty().bind(vSliderBind);

The reasoning is:

  • with super.bind() you set listeners to the properties from which the binding depends. This binding depends on the value of the slider and computes the height of the rectangle; thus you have to bind() it only to the value of the slider.
  • with computeValue() you do as it says: compute the actual output value (here: the height of the rect) whenever one or more of the bound properties change. Here the computation is a simple identity ( f(x)=x ), in other cases it may be more complex.

Another way to do it is adding a listener to the value property, then manually update the height.

like image 167
Nikos Paraskevopoulos Avatar answered Jan 02 '26 03:01

Nikos Paraskevopoulos