Issue
I want to make the user choose the color using the ColorPicker, and then use that color to change the color of a button. JavaFX
ColorPicker cp = new ColorPicker();
cp.setOnAction(e -> {
Color c = cp.getValue();
System.out.println(c);
});
In the println it will give answers like 0xe6e64dff,0xccffccff...
And if i want to color the button in say, blue, i would need to use this:
Button button = new Button();
button.setStyle("-fx-background-color: #ff0000; ");
So i assume i would have to convert the color value to a String before i can use it ? Or how do i go about this ? How do i get the picked color to be usable in the setStyle line?
Solution
Converting Color
to Hex String
You can use the following to create a hex string from a Color
:
private static String toHexString(Color color) {
int r = ((int) Math.round(color.getRed() * 255)) << 24;
int g = ((int) Math.round(color.getGreen() * 255)) << 16;
int b = ((int) Math.round(color.getBlue() * 255)) << 8;
int a = ((int) Math.round(color.getOpacity() * 255));
return String.format("#%08X", (r + g + b + a));
}
This will also include the alpha (i.e. opacity) of the color. Note that the JavaFX CSS Reference Guide does not document any support for 4-digit/8-digit hex values:
RGB Hex: The format of an RGB value in hexadecimal notation is a ‘#’ immediately followed by either three or six hexadecimal characters. The three-digit RGB notation (#rgb) is converted into six-digit form (#rrggbb) by replicating digits, not by adding zeros. For example, #fb0 expands to #ffbb00. This ensures that white (#ffffff) can be specified with the short notation (#fff) and removes any dependencies on the color depth of the display.
However, the documentation of Color#web(String)
says the following format is supported:
An HTML long or short format hex string with an optional hex alpha channel [emphasis added]. Hexadecimal values may be preceded by either
"0x"
or"#"
and can either be 2 digits in the range00
to0xFF
or a single digit in the range0
toF
.
Also note it says the hexadecimal value may be prefixed with either 0x
or #
.
Here's an example using the above utility method:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ColorPicker;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class App extends Application {
@Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
ColorPicker picker = new ColorPicker();
root.getChildren().add(picker);
picker.setOnAction(
event -> {
event.consume();
Color value = picker.getValue();
if (value == null) {
root.setStyle(null);
} else {
String style = String.format("-fx-background-color: %s;", toHexString(value));
root.setStyle(style);
}
});
primaryStage.setScene(new Scene(root, 500, 300));
primaryStage.setTitle("Color to Hexadecimal Example");
primaryStage.show();
}
private static String toHexString(Color color) {
int r = ((int) Math.round(color.getRed() * 255)) << 24;
int g = ((int) Math.round(color.getGreen() * 255)) << 16;
int b = ((int) Math.round(color.getBlue() * 255)) << 8;
int a = ((int) Math.round(color.getOpacity() * 255));
return String.format("#%08X", (r + g + b + a));
}
}
Background Property
There is another way to accomplish what you're doing. Instead of setting the style
, which requires converting the Color
to a String
, you can set the Region#background
property directly. Here's an example:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ColorPicker;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class App extends Application {
@Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
ColorPicker picker = new ColorPicker();
root.getChildren().add(picker);
picker.setOnAction(
event -> {
event.consume();
Color value = picker.getValue();
if (value == null) {
root.setBackground(null);
} else {
root.setBackground(new Background(new BackgroundFill(value, null, null)));
}
});
primaryStage.setScene(new Scene(root, 500, 300));
primaryStage.setTitle("Programmatically Set Background Color Example");
primaryStage.show();
}
}
Answered By - Slaw
Answer Checked By - Cary Denson (JavaFixing Admin)