javaFX自定义控制不良行为

时间:2015-05-01 19:18:16

标签: java javafx javafx-8

这个自定义控件是一个挂锁。我想要的是,当我点击它时,上部应旋转,底部应保持静止。现在,当我这样做时,底部也移动,我不明白为什么。有人可以帮助我找出为什么会发生这种情况以及如何避免它吗?

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);
    }

}

2 个答案:

答案 0 :(得分:1)

Group接受其子节点的并集。因此,如果在Group中移动形状,Group的边界可能会发生变化,导致其他子节点相对移动。

使用Pane作为皮肤的根,而不是Group

答案 1 :(得分:0)

在LockSkin中从Group更改为Pane容器,解决了这个问题。