2015-05-01 136 views
1

此自定义控件是挂锁。我想要的是,当我的鼠标点击它的上部应旋转,底部应保持静止。现在当我做到底部也移动,我不明白为什么。有人能帮我找出为什么会发生这种情况,以及如何避免它?javaFX自定义控件意外行为

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

} 
+0

尝试在皮肤中使用“窗格”,而不是“组”。 –

+0

谢谢,解决了这个问题,:)。 – user2288753

+0

您使用的是JDK?请注意,由于必须将8u40'getUserAgentStylesheet()'访问权限更改为public。 –

回答

1

A Group承担其子女的界限的联合。因此,如果在Group中移动形状,则Group的边界可能会更改,从而导致其他子节点相对于其移动。

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

0

从组改变到窗格容器中LockSkin,解决了这个问题。