3
\$\begingroup\$

Here is a simple hex color fetcher and analyzer in javafx that i wrote to understand multi-threading in javafx.

Demo on Linux

Questions:

  • Is my regex ok ? or if it can be improve?
  • I am not much familiar with javafx multi-threading so need know that i am doing it properly or not.
  • Need special attention on prepareTask() method.
  • Is my code readable ?
  • Anything else that you would like to improve.
/**
 *
 * @author Aamir khan
 */
public class HexAnalyzer extends Application {

    final String HEX_PATTERN = "#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})";
    final String CSS_URL = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css";
    Pattern pattern;
    TilePane colorsPane;
    TextField urlField;
    TextField colorVal;
    Button fetchBtn;

    @Override
    public void init() {
        pattern = Pattern.compile(HEX_PATTERN);
        urlField = new TextField(CSS_URL);
        fetchBtn = new Button("Fetch");
        colorVal = new TextField();
        colorsPane = new TilePane();
    }

    @Override
    public void start(Stage window) {

        fetchBtn.setPrefWidth(80.0);
        fetchBtn.setDefaultButton(true);

        colorVal.setFont(Font.font(14.0));
        colorVal.setVisible(false);

        HBox bar = new HBox(urlField, fetchBtn);
        bar.setSpacing(1.5);
        bar.setPadding(new Insets(5));

        HBox.setHgrow(urlField, Priority.ALWAYS);

        ScrollPane colorPane = new ScrollPane(colorsPane);
        colorPane.setFitToWidth(true);

        VBox root = new VBox(bar, colorPane, colorVal);

        window.setTitle("#HEX Color Analyzer");
        window.setScene(new Scene(root, 610, 400));
        window.show();

        fetchBtn.setOnAction(this::runTask);
    }

    boolean wasTaskStarted = false;

    private void runTask(ActionEvent e) {
        colorsPane.getChildren().clear();
        Service task = prepareTask();
        bindProperties(task);

        if (wasTaskStarted) {
            task.restart();
        } else {
            task.start();
            wasTaskStarted = true;
        }

    }

    private Service prepareTask() {
        return new Service() {
            @Override
            protected Task createTask() {
                return new Task<Void>() {
                    @Override
                    protected Void call() throws Exception {

                        try {

                            final String css = fetchDataFrom(urlField.getText());
                            final Set<String> hexColors = extractHexColors(css);

                            hexColors.forEach(color -> {
                                Rectangle colorBox = new Rectangle(40, 40, Color.web(color));
                                colorBox.setEffect(new DropShadow(3, Color.rgb(0, 0, 0, 0.5)));
                                colorBox.setUserData(color);

                                colorBox.setOnMouseClicked(ae -> {
                                    final String val = colorBox.getUserData().toString().toUpperCase();
                                    colorVal.setText(val);
                                });
                                Platform.runLater(() -> {
                                    colorsPane.getChildren().add(colorBox);
                                });
                            });
                        } catch (IOException ex) {
                            Alert alert = new Alert(AlertType.ERROR);
                            alert.setTitle("Error");
                            alert.setHeaderText("Oops, Something went wrong");
                            alert.setContentText(ex.toString());
                            alert.showAndWait();
                        }
                        return null;
                    }

                    //Util method to fetch data from the given url
                    private String fetchDataFrom(String url) throws IOException {
                        updateMessage("Fetching");
                        StringBuilder result = new StringBuilder();
                        URL cssurl = new URL(url);
                        URLConnection data = cssurl.openConnection();
                        try (BufferedReader in = new BufferedReader(
                                new InputStreamReader(
                                        data.getInputStream())
                        )) {
                            in.lines().forEach(result::append);
                        }
                        updateMessage("Done");

                        return result.toString();

                    }

                    //Util method to extract hex colors from the given String
                    private Set<String> extractHexColors(final String css) {
                        updateMessage("extracting hex");
                        Set<String> colorSet = new HashSet();
                        Matcher matcher = pattern.matcher(css);
                        while (matcher.find()) {
                            colorSet.add(matcher.group(0));
                        }
                        return colorSet;
                    }

                    @Override
                    public void succeeded() {
                        super.succeeded();
                        updateMessage("Fetch");//restrore the button
                        colorVal.setText("");//remove any previous val
                    }
                };
            }

        };
    }

    private void bindProperties(Service task) {
        fetchBtn.textProperty().bind(task.messageProperty());
        fetchBtn.disableProperty().bind(task.runningProperty());
        colorVal.visibleProperty().bind(task.runningProperty().not());
    }

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.