dnwjn
dnwjn

Reputation: 171

Java Node dynamic position on HBox

I use certain events to place small rectangles on an HBox. Their placement is perfect when the window has not been resized, but when you for example go from small to fullscreen, their placement is wrong (of course, because they get a certain value for X at the time of placement - this is measured by getting the width of the HBox at that specific moment).

Question:

How can I make these positions dynamic, so when I resize the window, they stay in proportion?

Pictures: Normal view Fullscreen

Code:

@FXML HBox tagLine; // initializes the HBox

...

public void addTag(String sort) {
    Rectangle rect = new Rectangle(20, tagLine.getHeight());
    double pos = timeSlider.getValue() / 100 * tagLine.getWidth(); // retrieves position at the moment of being called
    rect.setTranslateX(pos);
    rect.setOnMouseEntered(new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent event) {
            showNotification("Gemarkeerde gebeurtenis: " + sort);
        }
    });
    rect.setOnMouseExited(new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent event) {
            notificationHide.play();
        }
    });

    tagLine.getChildren().add(rect);
}

Upvotes: 0

Views: 793

Answers (1)

ItachiUchiha
ItachiUchiha

Reputation: 36792

Few things that you need to take into account while translating a shape with accountable size is that you need to :

  • Translate the shape from its center
  • If the translation is dependent on the width of a Node, listen to the changes made to the with of that particular node and make changes to the translate property accordingly

Both of the above points seem to be missing in your implementation. You are never listening to width property of HBox. Neither is your calculation for pos taking the center of Rectangle into account.

Here is an example which try to keep the Rectangle at the center no matter what the size of your HBox is.

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class Main extends Application {

    private static final int SIDE = 40;
    private static final double DEFAULT_WIDTH = 200;
    private static final double DEFAULT_POSITION = 100;

    @Override
    public void start(Stage primaryStage) {

        Rectangle rectangle = new Rectangle(SIDE, SIDE);
        HBox root = new HBox(rectangle);
        root.setPrefWidth(DEFAULT_WIDTH);

        rectangle.translateXProperty().bind(root.widthProperty().multiply(DEFAULT_POSITION/DEFAULT_WIDTH).subtract(SIDE/2));

        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

enter image description here

Upvotes: 2

Related Questions