user2288753
user2288753

Reputation: 35

javaFX custom control undesired behavior

this custom control is a padlock. what i want is that when i mouse click it the upper part should rotate and the bottom part should remain still. right now when i do it the bottom part also moves and i dont understand why. could someone help me to find out why this is happening and how to avoid it?

public class LockControl extends Application {

    @Override
    public void start(Stage primaryStage) {

        Lock lock = new Lock();
        lock.setTranslateX(150);
        lock.setTranslateY(200);


        Pane pane = new Pane(lock);
        //pane.setScaleShape(false);

        Scene scene = new Scene(pane, 800, 600);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}


public class Lock extends Control {

    private static final Color DEFAULT_LOCK_COLOR = Color.AQUA;
    private ObjectProperty<Paint> color;

    public void setColor(Paint value) {
        color.set(value);
    }

    public ObjectProperty<Paint> colorProperty() {
        if (null == color) {
            color = new StyleableObjectProperty<Paint>(DEFAULT_LOCK_COLOR) {
                @Override
                public CssMetaData getCssMetaData() {
                    return Lock.StyleableProperties.LOCK_COLOR;
                }

                @Override
                public Object getBean() {
                    return Lock.this;
                }

                @Override
                public String getName() {
                    return "lockColor";
                }
            };
        }
        return color;
    }

    @Override
    protected Skin createDefaultSkin() {
        return new LockSkin(this);
    }

    @Override
    protected String getUserAgentStylesheet() {
        return getClass().getResource("lock.css").toExternalForm();
    }
    // CSS STYLEABLE PROPERTIES

    public final Paint getColor() {
        return null == color ? DEFAULT_LOCK_COLOR : color.get();
    }

    private static class StyleableProperties {

        private static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES;
        private static final CssMetaData<Lock, Paint> LOCK_COLOR = new CssMetaData<Lock, Paint>("-lock-color", PaintConverter.getInstance(), DEFAULT_LOCK_COLOR) {

            @Override
            public boolean isSettable(Lock s) {
                return null == s.color || !s.color.isBound();
            }

            @Override
            public StyleableProperty<Paint> getStyleableProperty(Lock s) {
                return (StyleableProperty) s.colorProperty();
            }

            @Override
            public Paint getInitialValue(Lock s) {
                return (Color) s.getColor();
            }
        };

        static {
            final List<CssMetaData<? extends Styleable, ?>> styleables = new ArrayList<>(Control.getClassCssMetaData());
            Collections.addAll(styleables,
                    LOCK_COLOR
            );
            STYLEABLES = Collections.unmodifiableList(styleables);
        }
    }

    public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() {
        return StyleableProperties.STYLEABLES;
    }

    @Override
    public List<CssMetaData<? extends Styleable, ?>> getControlCssMetaData() {
        return getClassCssMetaData();
    }
}

public class LockSkin extends SkinBase<Lock> implements Skin<Lock> {

    private boolean rotated = false;


    public LockSkin(Lock c) {
        super(c);
        init();
        initGraphics();
    }

    private void init() {

    }

    private void initGraphics() {
        Group root = new Group();

        Path spade = new Path();//width:100, height:110
        spade.getElements().add(new MoveTo(0.0 , 100 ));
        spade.getElements().add(new CubicCurveTo(0 , 50, 25 , 25 , 50 , 25 ));
        spade.getElements().add(new CubicCurveTo(70 , 30 , 100 , 40, 100 , 100 ));
        spade.getElements().add(new LineTo(100 , 135 ));
        spade.getElements().add(new LineTo(80 , 135 ));
        spade.getElements().add(new LineTo(80 , 125 ));
        spade.getElements().add(new LineTo(84 , 125 ));
        spade.getElements().add(new LineTo(84 , 115 ));
        spade.getElements().add(new LineTo(80 , 115 ));
        spade.getElements().add(new LineTo(80 , 75 ));
        spade.getElements().add(new CubicCurveTo(80 , 70 , 80 , 65 , 78 , 60 ));
        spade.getElements().add(new CubicCurveTo(76 , 55 , 70 , 45 , 50 , 43 ));
        spade.getElements().add(new QuadCurveTo(40 , 44 , 35 , 50 ));
        spade.getElements().add(new QuadCurveTo(30 , 53 , 25 , 62 ));
        spade.getElements().add(new QuadCurveTo(20 , 67 , 19 , 100));
        spade.getElements().add(new LineTo(19 , 155 ));
        spade.getElements().add(new LineTo(0 , 155 ));
        spade.getElements().add(new LineTo(0 , 100 ));
        spade.setTranslateX(getSkinnable().getTranslateX());
        spade.setTranslateY(getSkinnable().getTranslateY());
        spade.setFill(getSkinnable().getColor());
        spade.setStroke(getSkinnable().getColor());
        spade.toBack();

        Rectangle rec = new Rectangle();
        rec.setWidth(115 );
        rec.setHeight(80 );
        rec.setTranslateX(getSkinnable().getTranslateX() - (8));
        rec.setTranslateY(getSkinnable().getTranslateY() + (115));
        rec.setTranslateZ(10);
        rec.setArcWidth(20);
        rec.setArcHeight(20);
        rec.setFill(getSkinnable().getColor());
        rec.setFocusTraversable(false);

        root.setStyle("-fx-align:center");
        root.getChildren().addAll(spade, rec);
        rec.setOnMouseEntered(c -> {
            spade.setTranslateY(spade.getTranslateY() - (25));
            RotateTransition rot = new RotateTransition();
            rot.setAxis(Rotate.Y_AXIS);
            rot.setToAngle(25);
            rot.setNode(spade);
            rot.setDuration(Duration.millis(50));
            rot.play();
        });

        rec.setOnMouseExited(t -> {
            if (rotated) {
                rotated = false;
                RotateTransition rot = new RotateTransition();
                rot.setAxis(Rotate.Y_AXIS);
                rot.setToAngle(0);
                rot.setNode(spade);
                rot.setDuration(Duration.millis(50));
                rot.play();
                spade.setTranslateX(spade.getTranslateX() +( 75));
                spade.setTranslateY(spade.getTranslateY() + (25));
            } else {

                RotateTransition rot = new RotateTransition();
                rot.setAxis(Rotate.Y_AXIS);
                rot.setToAngle(0);
                rot.setNode(spade);
                rot.setDuration(Duration.millis(50));
                rot.play();
                spade.setTranslateY(spade.getTranslateY() + (25));

            }
        });

        rec.setOnMouseClicked(t -> {
            if (!rotated) {
                rotated = true;
                RotateTransition rot = new RotateTransition();
                rot.setAxis(Rotate.Y_AXIS);
                rot.setToAngle(180);
                rot.setNode(spade);
                rot.setDuration(Duration.millis(50));
                rot.play();//20
                spade.setTranslateX(spade.getTranslateX() - (75));

            }
        });

        getChildren().setAll(root);
    }

}

Upvotes: 1

Views: 117

Answers (2)

James_D
James_D

Reputation: 209674

A Group takes on the union of the bounds of its children. Consequently, if you move shapes around in a Group, the bounds of the Group may change, causing other child nodes to move relatively to it.

Use a Pane as the root of the skin, instead of the Group.

Upvotes: 1

user2288753
user2288753

Reputation: 35

changing from Group to a Pane container in LockSkin , solved the problem.

Upvotes: 0

Related Questions