问题
I am writing a JavaFX program, where the user enters a color's Hex value and its set as a background color of StakePane. The code is:
stakePane.styleProperty().setValue("-fx-background-color: "+inputValue+";");
It works fine for a valid Hex value input.But when the user enters invalid Hex value its gives the following error on console:
javafx.scene.CssStyleHelper calculateValue
WARNING: Could not resolve '#E91E63g' while resolving lookups for '-fx-background-color' from inline style on ComboBox@20f56ee2[styleClass=combo-box-base combo-box]
I tried try catch
to handle this error. But the error is not caught.
JavaFX CSS Reference Guide says:
"Applications needing to detect errors from the parser can add a listener to the errors property of com.sun.javafx.css.StyleManager."
How can I handle CSS errors in javafx?
回答1:
There is no real java exception thrown on such an error. Instead only a warning is printed by the global StyleManager
that is responsible for applying the CSS to the Scene.
But happily the StyleManager
holds an observable list containing all errors that occurred. As stated by the reference guide you can simply add a listener to it. You get notified and you can handle errors accordingly.
com.sun.javafx.css.StyleManager.errorsProperty().addListener((ListChangeListener<? super CssError>) c -> {
while(c.next()) {
for(CssError error : c.getAddedSubList()) {
// maybe you want to check for specific errors here
System.out.println(error.getMessage());
}
}
});
But I think in your case it would be better to check the input string for a valid format before applying it to the CSS ;)
回答2:
You could simply validate the color before applying it to a stackpane. If the color is not a valid color then set a default color.
Below is a simple example that applies hex color values to a stackpane. The colorValues are stored in a comboBox. Now before setting the background color to stackpane, I call a method getColorValue(String colorValue). Now, if the color is a valid color then i set the color otherwise i print a message and set a default color. The default color in the below example is a Red color(#F00000).
To validate the color, i am using a regex.
private static final String HEX_PATTERN = "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$";
The regex is simple. It looks for a 6 letter value denoted by [A-Fa-f0-9]{6} or a 3 letter value denoted by [A-Fa-f0-9]{3}. The color value must start with a '#' sign.
public class ColorApp extends Application {
String backGroundColor = "";
@Override
public void start(Stage primaryStage) throws Exception {
Label messageLabel = new Label("Color NOT SELECTED FROM COMBOBOX");
ObservableList<String> options =
FXCollections.observableArrayList(
"DEFG",
"#ZZZAAA",
"#ABCDEF",
"#055"
);
StackPane stackPane = new StackPane();
final ComboBox comboBox = new ComboBox(options);
comboBox.setItems(options);
stackPane.getChildren().addAll(messageLabel,comboBox);
StackPane.setAlignment(messageLabel,Pos.TOP_LEFT);
comboBox.valueProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue observable, String oldValue, String newValue) {
backGroundColor = newValue;
stackPane.styleProperty().setValue("-fx-background-color: " + (backGroundColor = ColorUtils.getColorValue(backGroundColor)) + ";");
messageLabel.setText(backGroundColor + " Applied");
}
});
Scene scene = new Scene(stackPane,600,800);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
class ColorUtils {
private static final String HEX_PATTERN = "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$";
static Pattern pattern = Pattern.compile(HEX_PATTERN);
static Matcher matcher;
private static final String DEFAULT_COLOR_VALUE = "#F00000";
public static String getColorValue(String colorValue) {
matcher = pattern.matcher(colorValue);
boolean result = matcher.matches();
if (result == false) {
System.out.println("Invalid colorValue detected, colorValue==" + colorValue);
System.out.println("Setting default Color Value to RED");
return DEFAULT_COLOR_VALUE;
} else {
return colorValue;
}
}
}
If the color that was selected from comboBox got validated, the following output will be shown. Color Validated:
Color Not Validated:
Edit: Note that i am using a stackpane and manually setting a position to a label. This is not recommended.It is for demonstration purpose only.
来源:https://stackoverflow.com/questions/45255833/handling-css-errors-in-javafx