Handling CSS errors in Javafx

痞子三分冷 提交于 2020-08-09 12:31:06

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!