Obtener el color de fondo de un control JavaFX

publicado por: Anonymous

Quiero leer el color de fondo de un control desde código javaFX para luego aplicarle una transparencia. He estado buscando información pero no me aclaro. No hay ningún método getBackgroundColor() pero si getBackground() aunque ando perdidísimo ¿alguna idea?

solución

perdón por la respuesta kilométrica, tenía mucho tiempo que no usaba JavaFX y por lo mismo investigué un poco más a fondo.

Respuesta corta:

Puedes obtener los colores usados apra el fondo a aprtir de método getBackground, que a su vez dentro tiene una lista de los colores usados, y a menos que estés usando un gradiente o algo similar, el primer fill debería de ser el color único de fondo de tu objeto.

Color color = (Color) boton.getBackground().getFills().get(0).getFill();
System.out.println("color:"+color);

Respuesta larga:

Es importante que diferencies entre el color que se pone programáticamente y el que se pone desde estilo , ya que los estilos tienen mayor preferencia que los colores de fondo normales y pueden producir errores sutiles, que pueden o no obrar a nuestro favor y yo sugiero siempre usar colores programáticos en vez de estilos css de javafx.

Veamos un ejemplo simple, si tienes un fxml con un botón así:

<Button fx:id="btnrojillo" layoutX="16.0" layoutY="128.0" mnemonicParsing="false" onAction="#handleSubmitButtonAction" style="-fx-background-color: blue;" text="Button" />

y en tu handles de botón poes algo como:

@FXML
protected void handleSubmitButtonAction(ActionEvent event) {
    String style = btnrojillo.getStyle();

    System.out.println(style);
    btnrojillo.setStyle("-fx-background-color: red;");
    String colorDesdeEstilo = style.replaceAll(".*(-fx-background-color:\s?([a-zA-Z0-9]+)).*", "$2");


    System.out.println("color detectado desde hoja de estilos:" +
            colorDesdeEstilo
    );

    Color color = (Color) btnrojillo.getBackground().getFills().get(0).getFill();
    System.out.println("color detectado desde configuración de componente:" + color.toString().substring(2));
}

La primera vez que lo corras obtendrás un muy horrible NPE (No es lo que piensas picarón 😉 ) como este:

Caused by: java.lang.NullPointerException

at swinginterop.Model.handleSubmitButtonAction

Ahora si le metemos un selector de colores a nuestro

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ColorPicker?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="400.0" prefWidth="250.0" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="swinginterop.Model">
   <children>
      <AnchorPane layoutX="36.0" layoutY="47.0" prefHeight="266.0" prefWidth="258.0">
         <children>
            <ColorPicker fx:id="colorchooser" layoutX="11.0" layoutY="40.0" onAction="#handleColorSelectedAction" />
            <Button fx:id="btnrojillo" layoutX="16.0" layoutY="128.0" mnemonicParsing="false" onAction="#handleSubmitButtonAction" style="-fx-background-color: blue;" text="Button" />
         </children></AnchorPane>
   </children>
</AnchorPane>

Y en nuestro código Java

@FXML
protected void handleSubmitButtonAction(ActionEvent event) {
    String style = btnrojillo.getStyle();

    System.out.println(style);
    String colorDesdeEstilo = style.replaceAll(".*(-fx-background-color:\s?([a-zA-Z0-9]+)).*", "$2");


    System.out.println("color detectado desde hoja de estilos:" +
            colorDesdeEstilo
    );

    Color color = (Color) btnrojillo.getBackground().getFills().get(0).getFill();
    System.out.println("color detectado desde configuración de componente:" + color.toString().substring(2));
}


@FXML
protected void handleColorSelectedAction(ActionEvent event) {
    String value = colorchooser.getValue().toString().substring(2);
    btnrojillo.setBackground(new Background(new BackgroundFill(
                    colorchooser.getValue(), null, null
            )
            )
    );

}

Observaremos que el color solamente cambia temporalmente y regresa al color definido en el estilo.

Por ello es que te recomiendo si necesitas modificar el color hacerlo directamente en la propiedad style.

FXML:

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ColorPicker?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="400.0" prefWidth="250.0" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="swinginterop.Model">
   <children>
      <AnchorPane layoutX="36.0" layoutY="47.0" prefHeight="266.0" prefWidth="258.0">
         <children>
            <ColorPicker fx:id="colorchooser" layoutX="11.0" layoutY="40.0" onAction="#handleColorSelectedAction" />
            <Button fx:id="btnrojillo" layoutX="16.0" layoutY="128.0" mnemonicParsing="false" onAction="#handleSubmitButtonAction" style="-fx-background-color: blue;" text="Button" />
         </children></AnchorPane>
   </children>
</AnchorPane>

Java:

package swinginterop;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ColorPicker;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.stage.Stage;

public class Model extends Application {
    @FXML
    private Button btnrojillo;

    @FXML
    ColorPicker colorchooser;

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("FórmulasGrasa.fxml"));
        Scene scene = new Scene(root, 300, 275);

        stage.setTitle("FXML Welcome");
        stage.setScene(scene);
        stage.show();
    }

    @FXML
    protected void handleSubmitButtonAction(ActionEvent event) {
        String style = btnrojillo.getStyle();

        System.out.println(style);
        String colorDesdeEstilo = style.replaceAll(".*(-fx-background-color:\s?([a-zA-Z0-9]+)).*", "$2");


        System.out.println("color detectado desde hoja de estilos:" +
                colorDesdeEstilo
        );

        Color color = (Color) btnrojillo.getBackground().getFills().get(0).getFill();
        System.out.println("color detectado desde configuración de componente:" + color.toString().substring(2));
    }

    @FXML
    protected void handleColorSelectedAction(ActionEvent event) {
        String value = colorchooser.getValue().toString().substring(2);
        Paint red = Paint.valueOf(value);
        btnrojillo.setBackground(new Background(new BackgroundFill(
                        colorchooser.getValue(), null, null
                )
                )
        );

        btnrojillo.setStyle("-fx-background-color: #"+value+';');

    }

    public static void main(String args[]) {
        launch(args);
    }
}

Si de casualidad ocupas hacer binding al color te recomiendo leer esta pregunta en inglés.

Si ocupas transparencia puedes probar en el css con algo como:

-fx-background-color: none;

o si estás modificando directamente el Background desde código poniendo los fills en nulo.

Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *