如何防止循环绑定依赖

时间:2016-11-29 09:58:02

标签: java user-interface javafx data-binding javafx-8

我正在尝试创建一个文本区域,其中包含一个图像部分,类似于this

imageView.fitHeightProperty().bind(Bindings.createDoubleBinding(
    () -> textField.getHeight() -
          textField.getPadding().getTop() -
          textField.getPadding().getBottom(),
    textField.heightProperty(), textField.paddingProperty()));

imageView.fitWidthProperty().bind(imageView.fitHeightProperty());

textField.paddingProperty().bind(Bindings.createObjectBinding(
    () -> new Insets(textField.getPadding().getTop(),
                     textField.getPadding().getRight(),
                     textField.getPadding().getBottom(),
                     textField.getPadding().getRight() * 2 + imageView.getFitWidth()),
    imageView.fitWidthProperty(), textField.paddingProperty()));

我目前的做法是使用StackPane来保留TextField,然后添加ImageView作为StackPane的孩子。 ImageView需要知道如何调整自身大小,因此我将其fitHeight限制在TextField的高度,同时考虑TextField' s padding。

ImageView' s fitWidth然后绑定到自己的fitHeight

最后,我需要将TextField的文本偏移到右侧(因为图像阻止了它),所以我再次做了另一个依赖于{{1}的绑定{' s ImageView

这最终导致循环依赖,导致堆栈溢出。如果不对fitWidth左边填充进行硬编码,还有其他方法吗?

1 个答案:

答案 0 :(得分:0)

这是一个小例子,我使用过(StackPane/TextField/ImageView)但是我建议你用SVG绘制自己的形状来代替图像,以便完全控制它(MouseHover / Focused) ...),我也用CSS来实现这个目标:

Java:

    private StackPane sp = new StackPane();
    private TextField tf = new TextField();
    private ImageView iv;

    //Init StackPane
    sp.getStylesheets().add(getClass().getResource("style.css").toExternalForm()); 
    sp.getStyleClass().add("identifiant");
    sp.setPrefSize(200, 40);
    sp.setLayoutX(100);
    sp.setLayoutY(100);

    //Init ImageView
    iv = new ImageView(getClass().getResource("Img.png").toString());
    StackPane.setAlignment(iv, Pos.CENTER_LEFT);
    StackPane.setMargin(iv, new Insets(0, 0, 0, 10));

    //Init TextField
    StackPane.setAlignment(tf, Pos.CENTER_LEFT);
    StackPane.setMargin(tf, new Insets(2, 5, 0, 30));

    //Add all content
    sp.getChildren().addAll(iv,tf);

Css:

.identifiant{

-fx-background-color:#45444a;
-fx-effect:innershadow(three-pass-box , rgba(0,0,0) , 6, 0.0 , 0 , 0); 
-fx-background-radius:8px;
 }

.text-field{

-fx-background-insets:0;
-fx-background-color:#45444a;
-fx-text-fill:white;
}

希望这会对你有帮助!