JavaFX : Data binding pour changer la couleur d'un graphique (Line Chart)

Data binding avec de la couleur 🎨

Je vous recommande de lire l'article sur le data binding et les graphiques JavaFX. Vous trouverez le code complet pour cet application démo. Vous aurez juste à ajouter le code suivant pour modifier la couleur de la courbe ! 👍

Fichier FXML et CSS

Vous pouvez nommer le fichier chart-sin.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.chart.LineChart?>
<?import javafx.scene.chart.NumberAxis?>
<?import javafx.scene.control.ColorPicker?>
<?import javafx.scene.control.Slider?>
<?import javafx.scene.layout.VBox?>

<VBox id="root" fx:id="root" alignment="CENTER" spacing="20.0" stylesheets="@style.css" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fr.ronanlefichant.databinding.ChartColorController">
    <padding>
        <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
    </padding>
   <children>
      <LineChart fx:id="lineChart" animated="false" createSymbols="false">
        <xAxis>
          <NumberAxis side="BOTTOM" />
        </xAxis>
        <yAxis>
          <NumberAxis autoRanging="false" lowerBound="-3.0" side="LEFT" upperBound="3.0" />
        </yAxis>
      </LineChart>
      <Slider fx:id="slider" blockIncrement="0.25" majorTickUnit="0.25" max="2.5" min="-2.5" minorTickCount="0" snapToTicks="true" />
      <ColorPicker fx:id="colorPicker" minHeight="25.0" />
   </children>
</VBox>

Vous pouvez créer une variable dans le code CSS

.root {
-chart-custom-color0: #e00;
}

.default-color0.chart-series-line {
	-fx-stroke: -chart-custom-color0;
}

.default-color0.chart-line-symbol {
	-fx-background-color: -chart-custom-color0, white;
}

.default-color0 n'affectera que la première couleur. Si vous voulez d'autres couleurs, vous pouvez ajouter .default-color1, .default-color2 etc...

Nous allons pouvoir modifier la valeur de cet variable dans le contrôleur.

Le contrôleur

Notre contrôleur va implémenter Initializable. Il faut donc créer la fonction initialize

@Override
public void initialize(URL location, ResourceBundle resources) {

     //initialisation du slider et des autres composants et listener...

     /*
      * écoute les changements de valeur du color picker et appelle la fonction
      * onColorChanged
      */
      colorPicker.valueProperty().addListener(this::onColorChanged);
      colorPicker.setValue(Color.CHOCOLATE);
}

On ajoute un listener sur la valeur du color picker. Le listener appellera la fonction onColorChanged à chaque changement de couleur.

Vous pouvez changer la couleur du color picker maintenant que le listener est installé.

Il faut maintenant créer la fonction onColorChanged. Cette fonction va changer la couleur du graphique en changeant la variable du fichier CSS.

private void onColorChanged(ObservableValue << ? extends Color > colorObs, Color oldColor, Color newColor) {
    /* conversion au format web rgba(red,green,blue,opacity) */
    int red = (int)(newColor.getRed() * 255);
    int green = (int)(newColor.getGreen() * 255);
    int blue = (int)(newColor.getBlue() * 255);

    /* Locale US pour avoir un point à la place de la virgule pour l'opacité */
    String rgba = String.format(Locale.US, "rgba(%d,%d,%d,%.2f)", red, green, blue, newColor.getOpacity());

    /* change la valeur de la variable de style */
    root.setStyle("-chart-custom-color0: " + rgba + ";");
}

Si vous suivez l'article sur le data binding et les graphiques JavaFX vous devriez avoir le rendu suivant :

Commentaires