Issue
I have a kind of simple request to my application, but I am not sure which is the best solution for that.
Lets say I have 10 buttons and I want only one button with the opacity of 1.0. The buttons next to them should have 0.6 and the next ones 0.4. All other have 0.2.
Now I want a timeline which make a pulsating animation. The button which has the opacity of 1.0 should go to 0.2 until the previous button start raising the opacity and reached the value of 0.4.
I can't describe it better right now, but I think most people know the effect.
First attempt
Creating 10 timelines and start each timeline when finishing another - but I hope there is a solution with just one timeline
Second attempt
One timeline where each KeyFrame has a delay before starting - but I found just a delay for the whole animation.
Here's a minimal example, but I don't think that really helps because that's just the base.
package com.example.demo;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class HelloApplication extends Application {
@Override
public void start(Stage stage) throws IOException {
List<Button> allButtons = new ArrayList<>();
VBox vBox = new VBox(20);
for (int i = 0; i < 10; i++) {
Button button = new Button("Test");
button.setOpacity(0.2);
allButtons.add(button);
vBox.getChildren().add(button);
}
allButtons.get(1).setOpacity(0.4);
allButtons.get(2).setOpacity(0.6);
allButtons.get(3).setOpacity(1.0);
allButtons.get(4).setOpacity(0.6);
allButtons.get(5).setOpacity(0.4);
Scene scene = new Scene(vBox, 1200, 800);
stage.setScene(scene);
stage.show();
}
}
Exmple opacity values during the iterations
Iteration | Button A | Button B | Button C | Button D | Button E | Button F | Button G | Button H |
---|---|---|---|---|---|---|---|---|
1 | 0.2 | 0.2 | 0.4 | 0.6 | 1.0 | 0.6 | 0.4 | 0.2 |
2 | 0.2 | 0.2 | 0.2 | 0.4 | 0.6 | 1.0 | 0.6 | 0.4 |
3 | 0.4 | 0.2 | 0.2 | 0.2 | 0.4 | 0.6 | 1.0 | 0.6 |
4 | 0.6 | 0.4 | 0.2 | 0.2 | 0.2 | 0.4 | 0.6 | 1.0 |
5 | 1.0 | 0.6 | 0.4 | 0.2 | 0.2 | 0.2 | 0.4 | 0.6 |
6 | 0.6 | 1.0 | 0.6 | 0.4 | 0.2 | 0.2 | 0.2 | 0.4 |
7 | 0.4 | 0.6 | 1.0 | 0.6 | 0.4 | 0.2 | 0.2 | 0.2 |
8 | 0.2 | 0.4 | 0.6 | 1.0 | 0.6 | 0.4 | 0.2 | 0.2 |
And then start again from iteration 1. Also a transition between those opacity values should be used so that it is a smooth transition between thos opacity values.
Many greetings, Hauke
Solution
This code uses Timeline
, FadeTransition
, and ParallelTransition
to change the opacity of the buttons every second.
import java.util.ArrayList;
import java.util.List;
import javafx.animation.Animation;
import javafx.animation.FadeTransition;
import javafx.animation.KeyFrame;
import javafx.animation.ParallelTransition;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;
public class App extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
VBox vBox = new VBox();
vBox.setSpacing(2);
List<String> buttonTextList = new ArrayList();
buttonTextList.add("A");
buttonTextList.add("B");
buttonTextList.add("C");
buttonTextList.add("D");
buttonTextList.add("E");
buttonTextList.add("F");
buttonTextList.add("G");
buttonTextList.add("H");
FadeTransition ftStepOne = new FadeTransition(Duration.seconds(.9));
ftStepOne.setToValue(0.2);
FadeTransition ftStepTwo = new FadeTransition(Duration.seconds(.9));
ftStepTwo.setToValue(0.2);
FadeTransition ftStepThree = new FadeTransition(Duration.seconds(.9));
ftStepThree.setToValue(0.4);
FadeTransition ftStepFour = new FadeTransition(Duration.seconds(.9));
ftStepFour.setToValue(0.6);
FadeTransition ftStepFive = new FadeTransition(Duration.seconds(.9));
ftStepFive.setToValue(1.0);
FadeTransition ftStepSix = new FadeTransition(Duration.seconds(.9));
ftStepSix.setToValue(0.6);
FadeTransition ftStepSeven = new FadeTransition(Duration.seconds(.9));
ftStepSeven.setToValue(0.4);
FadeTransition ftStepEight = new FadeTransition(Duration.seconds(.9));
ftStepEight.setToValue(0.2);
List<FadeTransition> buttonStateList = new ArrayList();
buttonStateList.add(ftStepOne);
buttonStateList.add(ftStepTwo);
buttonStateList.add(ftStepThree);
buttonStateList.add(ftStepFour);
buttonStateList.add(ftStepFive);
buttonStateList.add(ftStepSix);
buttonStateList.add(ftStepSeven);
buttonStateList.add(ftStepEight);
List<Button> allButtons = new ArrayList<>();
for (int i = 0; i < buttonTextList.size(); i++) {
Button button = new Button(buttonTextList.get(i));
button.setPrefWidth(100);
button.setStyle("-fx-background-color: blue;");
allButtons.add(button);
vBox.getChildren().add(button);
}
final ParallelTransition parallelTransition = new ParallelTransition ();
parallelTransition.getChildren().addAll(buttonStateList);
final Timeline timeleine = new Timeline(
new KeyFrame(Duration.seconds(1), (ActionEvent event) -> {
for(int i = 0; i < allButtons.size(); i++)
{
System.out.println(allButtons.get(i).getText() + "\tFrom: " + allButtons.get(i).getOpacity() + "\tTo: " + buttonStateList.get(i).getToValue());
buttonStateList.get(i).setNode(allButtons.get(i));
}
parallelTransition.play();
FadeTransition addFtToEnd = buttonStateList.get(0);
buttonStateList.remove(addFtToEnd);
buttonStateList.add(addFtToEnd);
}));
timeleine.setCycleCount(Timeline.INDEFINITE);
Button startBtn = new Button("Start");
startBtn.setOnAction(event ->{
if(timeleine.getStatus() == Animation.Status.STOPPED || timeleine.getStatus() == Animation.Status.PAUSED)
{
timeleine.play();
startBtn.setText("Stop");
System.out.println(timeleine.getStatus());
}
else if(timeleine.getStatus() == Animation.Status.RUNNING)
{
timeleine.pause();
startBtn.setText("Start");
}
});
vBox.getChildren().add(startBtn);
Scene scene = new Scene(vBox, 1200, 800);
primaryStage.setScene(scene);
primaryStage.show();
}
}
Answered By - SedJ601
Answer Checked By - Senaida (JavaFixing Volunteer)