Java 8 如何用JavaFX画一条线

Java 8 如何用JavaFX画一条线,java-8,javafx-8,Java 8,Javafx 8,我有下面的代码,我正在尝试创建4个标签,其中两个在两个VBox中。我想用一条线连接这些VBox 我无法找到正确的x、y值以将线放置在正确的位置 @Override public void start(Stage primaryStage) { Group root = new Group(); Scene scene = new Scene(root); Label label1 = new Label("Info \n 1"); label1.setSt

我有下面的代码,我正在尝试创建4个标签,其中两个在两个VBox中。我想用一条线连接这些VBox

我无法找到正确的x、y值以将线放置在正确的位置

@Override
public void start(Stage primaryStage) {

    Group root = new Group();
    Scene scene = new Scene(root);

    Label  label1  = new Label("Info \n 1");
    label1.setStyle("-fx-border-color: black;-fx-padding: 10px;");
    label1.setWrapText(true);

    Label  label2  = new Label("Info 2222222222222");
    label2.setStyle("-fx-border-color: black;-fx-padding: 10px;");
    label2.setWrapText(true);

    VBox vbox1 = new VBox(5);
    vbox1.setMaxWidth(50);
    vbox1.getChildren().add(label1);
    vbox1.getChildren().add(label2);

    Label  label3  = new Label("Info \n 3");
    label3.setStyle("-fx-border-color: black;-fx-padding: 10px;");
    label3.setWrapText(true);

    Label  label4  = new Label("Info 444444444444444444");
    label4.setStyle("-fx-border-color: black;-fx-padding: 10px;");
    label4.setWrapText(true);

    VBox vbox2 = new VBox(5);
    vbox2.setMaxWidth(50);
    vbox2.getChildren().add(label3);
    vbox2.getChildren().add(label4);

    HBox hbox = new HBox(100);
    hbox.getChildren().addAll(vbox1, vbox2);

    Bounds bounds = label1.getBoundsInLocal();
    double startX = bounds.getMaxX();
    double startY = (bounds.getMaxY() - bounds.getMinY()) /2;

    Line line = new Line(startX, startY, startX+100, startY);   
    line.setStrokeWidth(5); 
    line.setStroke(Color.BLACK); 

    Pane stack = new Pane();
    stack.getChildren().addAll(hbox, line);

    root.getChildren().addAll(stack);

    primaryStage.setScene(scene);
    primaryStage.show();

直到第一个脉冲(即直到实际执行布局)才计算布局边界。解决此问题的最佳方法是使用绑定

此外,您使用的是标签的局部边界,而不是相对于行所在容器的边界。您需要进行适当的转换

我不太清楚您试图连接什么,但本例将连接
label1
label3

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.DoubleBinding;
import javafx.beans.binding.ObjectBinding;
import javafx.geometry.Bounds;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.stage.Stage;

public class ConnectedVBoxes extends Application {

    @Override
    public void start(Stage primaryStage) {

        Group root = new Group();
        Scene scene = new Scene(root);

        Label  label1  = new Label("Info \n 1");
        label1.setStyle("-fx-border-color: black;-fx-padding: 10px;");
        label1.setWrapText(true);

        Label  label2  = new Label("Info 2222222222222");
        label2.setStyle("-fx-border-color: black;-fx-padding: 10px;");
        label2.setWrapText(true);

        VBox vbox1 = new VBox(5);
        vbox1.setMaxWidth(50);
        vbox1.getChildren().add(label1);
        vbox1.getChildren().add(label2);

        Label  label3  = new Label("Info \n 3");
        label3.setStyle("-fx-border-color: black;-fx-padding: 10px;");
        label3.setWrapText(true);

        Label  label4  = new Label("Info 444444444444444444");
        label4.setStyle("-fx-border-color: black;-fx-padding: 10px;");
        label4.setWrapText(true);

        VBox vbox2 = new VBox(5);
        vbox2.setMaxWidth(50);
        vbox2.getChildren().add(label3);
        vbox2.getChildren().add(label4);

        HBox hbox = new HBox(100);
        hbox.getChildren().addAll(vbox1, vbox2);


        Line line = new Line();   
        line.setStrokeWidth(5); 
        line.setStroke(Color.BLACK); 

        Pane stack = new Pane();
        stack.getChildren().addAll(hbox, line);

        ObjectBinding<Bounds> label1InStack = Bindings.createObjectBinding(() -> {
            Bounds label1InScene = label1.localToScene(label1.getBoundsInLocal());
            return stack.sceneToLocal(label1InScene);
        }, label1.boundsInLocalProperty(), label1.localToSceneTransformProperty(), stack.localToSceneTransformProperty());

        ObjectBinding<Bounds> label3InStack = Bindings.createObjectBinding(() -> {
            Bounds label3InScene = label3.localToScene(label3.getBoundsInLocal());
            return stack.sceneToLocal(label3InScene);
        }, label3.boundsInLocalProperty(), label3.localToSceneTransformProperty(), stack.localToSceneTransformProperty());

        DoubleBinding startX = Bindings.createDoubleBinding(() -> label1InStack.get().getMaxX(), label1InStack);
        DoubleBinding startY = Bindings.createDoubleBinding(() -> {
            Bounds b = label1InStack.get();
            return b.getMinY() + b.getHeight() / 2 ;
        }, label1InStack);

        DoubleBinding endX = Bindings.createDoubleBinding(() -> label3InStack.get().getMinX(), label3InStack);
        DoubleBinding endY = Bindings.createDoubleBinding(() -> {
            Bounds b = label3InStack.get();
            return b.getMinY() + b.getHeight() / 2 ;
        }, label3InStack);

        line.startXProperty().bind(startX);
        line.startYProperty().bind(startY);
        line.endXProperty().bind(endX);
        line.endYProperty().bind(endY);


        root.getChildren().addAll(stack);

        primaryStage.setScene(scene);
        primaryStage.show();    
    }

    public static void main(String[] args) {
        launch(args);
    }
}
导入javafx.application.application;
导入javafx.beans.binding.Bindings;
导入javafx.beans.binding.DoubleBinding;
导入javafx.beans.binding.ObjectBinding;
导入javafx.geometry.Bounds;
导入javafx.scene.Group;
导入javafx.scene.scene;
导入javafx.scene.control.Label;
导入javafx.scene.layout.HBox;
导入javafx.scene.layout.Pane;
导入javafx.scene.layout.VBox;
导入javafx.scene.paint.Color;
导入javafx.scene.shape.Line;
导入javafx.stage.stage;
公共类ConnectedVBoxes扩展了应用程序{
@凌驾
公共无效开始(阶段primaryStage){
组根=新组();
场景=新场景(根);
Label label1=新标签(“信息\n 1”);
标签1.setStyle(“-fx边框颜色:黑色;-fx填充:10px;”);
标签1.setWrapText(真);
标签2=新标签(“信息22222”);
标签2.setStyle(“-fx边框颜色:黑色;-fx填充:10px;”);
label2.setWrapText(真);
VBox vbox1=新的VBox(5);
vbox1.setMaxWidth(50);
vbox1.getChildren().add(label1);
vbox1.getChildren().add(label2);
Label label3=新标签(“信息\n 3”);
标签3.setStyle(“-fx边框颜色:黑色;-fx填充:10px;”);
label3.setWrapText(真);
标签4=新标签(“信息4444”);
标签4.setStyle(“-fx边框颜色:黑色;-fx填充:10px;”);
label4.setWrapText(真);
VBox vbox2=新的VBox(5);
vbox2.setMaxWidth(50);
vbox2.getChildren().add(label3);
vbox2.getChildren().add(label4);
HBox HBox=新的HBox(100);
hbox.getChildren().addAll(vbox1,vbox2);
行=新行();
线设置行程宽度(5);
线。设定行程(颜色。黑色);
窗格堆栈=新窗格();
stack.getChildren().addAll(hbox,line);
ObjectBinding label1InStack=Bindings.createObjectBinding(()->{
Bounds label1InScene=label1.localToScene(label1.getBoundsInLocal());
返回stack.sceneToLocal(label1InScene);
},label1.boundsInLocalProperty(),label1.LocalToScenetTransformProperty(),stack.LocalToScenetTransformProperty());
ObjectBinding label3InStack=Bindings.createObjectBinding(()->{
边界label3InScene=label3.localToScene(label3.getBoundsInLocal());
返回堆栈。场景局部(label3InScene);
},label3.boundsInLocalProperty(),label3.LocalToScenetTransformProperty(),stack.LocalToScenetTransformProperty());
DoubleBinding startX=Bindings.createDoubleBinding(()->label1InStack.get().getMaxX(),label1InStack);
DoubleBinding startY=Bindings.createDoubleBinding(()->{
边界b=label1InStack.get();
返回b.getMinY()+b.getHeight()/2;
},label1InStack);
DoubleBinding endX=Bindings.createDoubleBinding(()->label3InStack.get().getMinX(),label3InStack);
DoubleBinding endY=Bindings.createDoubleBinding(()->{
边界b=label3InStack.get();
返回b.getMinY()+b.getHeight()/2;
},Label3安装);
line.startXProperty().bind(startX);
line.startYProperty().bind(startY);
line.endXProperty().bind(endX);
line.endYProperty().bind(endY);
root.getChildren().addAll(堆栈);
初级阶段。场景(场景);
primaryStage.show();
}
公共静态void main(字符串[]args){
发射(args);
}
}

使用此技术,即使用户调整窗口大小时标签移动(或出于其他原因),线路仍保持连接标签的状态。

您是否尝试在线路上使用
setTranslateX()
setTranslateY()
?非常感谢!!那奏效了。。我把它作为一个更大的应用程序的一部分,我想在其中显示几个链接框。。我刚刚在这里放了一个样品