两个圆之间的JavaFX线和圆心在文本中居中

我正在尝试为二进制搜索树编写一个程序,该程序会将圆圈放在JavaFX的窗格中,然后将圆圈与一行连接起来,使其看起来像 二进制搜索树。我可以使圆出现在窗格中,但是正在创建的线保持在顶部,并且不会从父圆的中心到新圆的中心。我也希望文本在圆圈内居中,但我也无法使其正常工作。我在下面将我的代码以及我的输出和所需的输出一起发布了。

public boolean addNode(T addMe) {
    boolean added = false;
    MyNode current = root;
    MyNode node = new MyNode(addMe,null,null);
    if (root == null) {
        root = node;
        added = true;
    } else {
        while (added != true) {
            if (addMe.compareTo(current.info) < 0) {
                if (current.left == null) {
                    current.left =  new MyNode(addMe,null);
                    added = true;
                } else {
                    current = current.left;
                }
            } else {
                if (current.right == null) {
                    current.right =  new MyNode(addMe,null);
                    added = true;
                } else {
                    current = current.right;
                }
            }
        }
    }
    node.label = new Text("" + addMe);
    node.label.setfont(new Font(16));
    node.circle = encircle(node.label,node);
    node.label.xProperty().bind(node.circle.centerXProperty());
    node.label.yProperty().bind(node.circle.centerYProperty());
    node.edge = new Line();
    if(node != root) {   
        node.edge.startXProperty().bind(current.circle.centerXProperty());
        node.edge.endXProperty().bind(node.circle.centerXProperty());
    }
    this.getchildren().add(node.edge);
    node.edge.toBack();

    node.circle.setOnmouseDragged(evt -> {
        double mouseX = evt.getX(),mouseY = evt.getY();
        node.circle.setCenterX(mouseX);
        node.circle.setCenterY(mouseY);
    });
    this.getchildren().addAll(node.circle,node.label);
    return added;
}

private Circle encircle(Text text,MyNode node) {
    node.circle = new Circle();
    node.circle.setfill(Color.WHITE);
    final double PADDING = 10;
    node.circle.setRadius(getWidth(text) / 2 + PADDING);
    if (node == root) {
        node.circle.setStroke(Color.RED);
    } else {
        node.circle.setStroke(Color.BLACK);
    }
    return node.circle;
}

private int getWidth(Text text) {
    new Scene(new Group(text));
    text.applyCss();
    return (int) text.getLayoutBounds().getWidth();
}

我的输出:My Output 所需的输出:Desired Output

jchl_wyl 回答:两个圆之间的JavaFX线和圆心在文本中居中

关于行的位置,您绑定了x值,却忘记了绑定y值。

node.edge.startYProperty().bind(current.circle.centerYProperty());
node.edge.endYProperty().bind(node.circle.centerYProperty());

关于放置文本,您需要将文本移动到其边界的一半以将其定位到给定位置的中心。以下代码可能有效。

node.label.xProperty().bind(node.circle.centerXProperty().subtract(node.circle.radiusProperty().subtract(10))); // Your PADDING value
node.label.yProperty().bind(node.circle.centerYProperty().subtract(node.circle.radiusProperty().subtract(10))); // Your PADDING value

如果您提供一个简单的示例,我可以为您提供更准确的解决方案。

每种实现可以有很多方法。出于以下原因,下面是我可以使用的一种方法:

  • 将类似的内容归为一类
  • 避免额外的Circle节点
  • 不要担心文本的位置。

这些只是我的观点,不确定是否能为您提供帮助。

    import javafx.application.Application;
import javafx.beans.binding.DoubleBinding;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.shape.Line;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class BinarySearchLayoutDemo extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        Pane root = new Pane();
        Scene scene = new Scene(root,400,400);
        primaryStage.setScene(scene);
        primaryStage.show();

        InfoNode node1 = buildAndAddNode(root,null,"345785",100,100);
        InfoNode node2 = buildAndAddNode(root,node1,"2356",200,200);
        InfoNode node3 = buildAndAddNode(root,"589",50,200);
        InfoNode node4 = buildAndAddNode(root,node2,"478",280,300);
        InfoNode node5 = buildAndAddNode(root,"25",150,300);
    }

    private InfoNode buildAndAddNode(Pane root,InfoNode parentNode,String text,double x,double y) {
        InfoNode node = new InfoNode(text);
        node.setPosition(x,y);
        root.getChildren().add(node);
        if (parentNode != null) {
            Line line = new Line();
            line.startXProperty().bind(parentNode.centerXProperty());
            line.startYProperty().bind(parentNode.centerYProperty());
            line.endXProperty().bind(node.centerXProperty());
            line.endYProperty().bind(node.centerYProperty());
            root.getChildren().add(line);
            line.toBack();
        }
        return node;
    }

    class InfoNode extends StackPane {
        private double PADDING = 8;
        private double x;
        private double y;

        public InfoNode(String txt) {
            Text text = new Text(txt);
            double size = getWidth(text) + (2 * PADDING);
            setStyle("-fx-shape:\"M 0 0 m -5,0 a 5,5 0 1,0 10,0 -10,0\";-fx-border-color:black;-fx-border-width:1px;-fx-background-color:yellow;");
            setMinSize(size,size);
            getChildren().add(text);

            widthProperty().addListener((obs,old,val) -> setLayoutX(x - val.doubleValue() / 2));
            heightProperty().addListener((obs,val) -> setLayoutY(y - val.doubleValue() / 2));
        }

        public DoubleBinding centerXProperty() {
            return layoutXProperty().add(widthProperty().divide(2));
        }

        public DoubleBinding centerYProperty() {
            return layoutYProperty().add(heightProperty().divide(2));
        }

        public void setPosition(double x,double y) {
            this.x = x;
            this.y = y;
            setLayoutX(x - getWidth() / 2);
            setLayoutY(y - getHeight() / 2);
        }

        private double getWidth(Text text) {
            new Scene(new Group(text));
            text.applyCss();
            return text.getLayoutBounds().getWidth();
        }
    }
}
本文链接:https://www.f2er.com/3127801.html

大家都在问