I'm trying to make an animated button by gradually changing it's style using a CSS file.
I researched about it, and I got to this this question. I saw the accepted answer and I tried to implement the solution that that person gave.
What I did is basically creating a CustomButton class that extends Button, and then setting up StringProperties whose values change depending on if the button is clicked or not; then, every single StringProperty is concatenated so then they work as an alternative to a CSS file, being applied as a style to a button.
I think everything is coded fine, the problem is that I can't create the animation that should be played when the button is pressed because for that I'd need to create a Timeline whose Keyframe's KeyValues specify the value of each one of the components that conform the animation, and it turns out that StringProperties can't work as parameters for a KeyValue method.
This is the CustomButton class:
public class CustomButton extends Button{
BooleanProperty clicked = new SimpleBooleanProperty(false); // Its value changes each time the button is clicked.
StringProperty oldRotationValue = new SimpleStringProperty("-fx-rotate: -360;"); // Stores the last value of rotationStringProperty, so
// then it can be used as the first frame of an animation.
StringProperty oldColorValue = new SimpleStringProperty("#E74C3C;"); // Stores the last value of colorStringProperty, so
// then it can be used as the first frame of an animation.
StringProperty oldSizeValue = new SimpleStringProperty("-fx-size: " + "180px;"); // Stores the last value of sizeStringProperty, so
// then it can be used as the first frame of an animation.
public CustomButton(){
Button button = createButton(rotationStringProperty, colorStringProperty, sizeStringProperty);
} //CustomButton constructor
StringProperty rotationStringProperty = new SimpleStringProperty(); // Creates the rotationStringProperty.
StringProperty colorStringProperty = new SimpleStringProperty(); // Creates the colorStringProperty.
StringProperty sizeStringProperty = new SimpleStringProperty(); // Creates the sizeStringProperty.
private void setRotationStringProperty() { // Method that sets the rotation value depending on whether the button was pressed or not.
if (!clicked.getValue()) { // If the button wasn't clicked.
oldRotationValue.set("-fx-rotate: " + "-360;");
rotationStringProperty.set("-fx-rotate: " + "360;");
} else { // If the button was clicked.
oldRotationValue.set("-fx-rotate: " + "360;");
rotationStringProperty.set("-fx-rotate: " + "-360;");
}
}
private StringProperty setColorStringProperty() { // Method that sets the color depending on whether the button was pressed or not.
if (!clicked.getValue()) { // If the button wasn't clicked.
oldColorValue.set("#EA6153;");
colorStringProperty.set("#E74C3C;");
} else { // If the button was clicked.
oldColorValue.set("#E74C3C;");
colorStringProperty.set("#EA6153;");
}
}
private StringProperty setSizeStringProperty() { // Method that sets the size depending on whether the button was pressed or not.
if (!clicked.getValue()) { // If the button wasn't pressed
oldSizeValue.set("-fx-size: " + "200px;");
sizeStringProperty.set("-fx-size: " + "180px;");
} else { // If the button was pressed.
oldSizeValue.set("-fx-size: " + "180px;");
sizeStringProperty.set("-fx-size: " + "200px;");
}
}
private void setSizeStringMediumProperty(){ // Sets the size that the button must have in the middle of the animation.
if(!clicked.getValue()){ // If the button wasn't pressed.
sizeStringProperty.set("-fx-size: " + "170px;");
}else{ // If the button was pressed.
sizeStringProperty.set("-fx-size: " + "210px;");
}
}
private Button createButton(StringProperty rotationStringProperty, //Method that creates a button and defines the its rotation,
// color, size, and how these has to be animated.
// Once everything is done, it returns the customized button.
StringProperty colorStringProperty,
StringProperty sizeStringProperty) {
Button button = new Button(); // Creates a normal JavaFX Button so then it can be modified.
buttonSetOnAction(button); // Sets the action that the button must perform when it's clicked.
setRotationStringProperty(); // Sets the rotationStringProperty.
setColorStringProperty(); // Sets the colorStringProperty.
setSizeStringProperty(); // Sets the sizeStringProperty.
button.styleProperty().bind(new SimpleStringProperty("-fx-background-color: ") // Set's the style of the button.
.concat(colorStringProperty)
.concat(sizeStringProperty)
.concat(rotationStringProperty)
.concat("fx-border-color; #c0392b;")
.concat("-fx-border-width: 15px;"));
return button; // Returns the button.
}
private void buttonSetOnAction(Button button){ // Definition of a method that sets the actions that the button must perform when it's clicked.
button.setOnAction(e -> {
clicked.set(!clicked.getValue()); // The value of clicked is set to its opposite.
Timeline animation = new Timeline( //Defines an animation
new KeyFrame(Duration.seconds(0), new KeyValue(oldRotationValue, oldColorValue, oldSizeValue));
setSizeStringMediumProperty(); // Sets the size that the button must have at the middle of the animation.
new KeyFrame(Duration.seconds(0.25), new KeyValue(sizeStringProperty));
setSizeStringProperty(); // Sets the size that the button must have at the end of the animation.
new KeyFrame(Duration.seconds(0.50), new KeyValue(rotationStringProperty, colorStringProperty, sizeStringProperty));
);
animation.play(); // Plays the animation;
});
}
}
Can anyone think of an alternative to using StringProperties?
NOTE: I know that "-fx-size: " does nothing, but I don't know how to change the button's size in CSS. I'll ask that in another question once I can solve the animation problem.
Thanks in advance.
Aucun commentaire:
Enregistrer un commentaire