HanSolo / medusa

A JavaFX library for Gauges
Apache License 2.0
688 stars 129 forks source link

Skins are missing initial width/height change #145

Closed protogenes closed 6 years ago

protogenes commented 6 years ago

During skin construction registerListeners() is called last, but width and height of the control change during initGraphics() when adding the children. This results in wrong layout of the skin when no further layout change happens.

using: Oracle VM 1.8.172 on Windows gauge-error

HanSolo commented 6 years ago

Can you provide a code snippet that reproduces the issue please?

protogenes commented 6 years ago

Sorry for the late reply, I had a hard time finding the root of all evil™. The pitfall is a ChangeListener on the layoutBounds of a Group which is an anchestor of the Gauge. Minimal sample application:

import eu.hansolo.medusa.Gauge;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class TestApplication extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception {
        Gauge gauge = new Gauge(Gauge.SkinType.LCD);

        Group group = new Group();
        group.setMouseTransparent(true);

        StackPane root = new StackPane(group);
        root.setOnMouseClicked(e -> gauge.setPrefSize(root.getWidth() / 4, root.getHeight() / 4));

        primaryStage.setScene(new Scene(root));
        primaryStage.show();

        group.layoutBoundsProperty().addListener((o, ov, nv) -> {});
        group.getChildren().add(gauge);
    }
}
HanSolo commented 6 years ago

Ok...with your code I see the problem and will take a look at it. I guess you know it but nevertheless it is not a good idea to add/remove nodes to the scene graph after it has been initialized. You could simply avoid this problem by adding the gauge before the stage will be shown e.g. Group group = new Group(gauge);

HanSolo commented 6 years ago

Where did you see that effect originally? In SceneBuilder?

protogenes commented 6 years ago

This happens in the gui builder part of our application, which is not based on SceneBuilder. I know there are performance considerations when changing an initialised scene graph, but modifications are dictated by the dynamic nature of gui builders. For now I removed the listener on layoutBounds and wait for the layout pass to set needsLayout to false instead.

HanSolo commented 6 years ago

Should be fixed with last commit (7f21691e1e0d6f23938144c744a96e52c6ab)