0
votes

I'm interested how I can hide Context menu when I drag the main Stage or window? I'm working on this Validator example and I noticed several problems related to the Context Menu in Java 8

public class MainApp extends Application
{

    @Override
    public void start(Stage stage) throws Exception
    {

//        setUserAgentStylesheet(STYLESHEET_CASPIAN);
        stage.setTitle("Validation Demo");
        BorderPane borderPane = new BorderPane();

        borderPane.setCenter(loadLoginScreen());
        Scene scene = new Scene(borderPane, 700, 500);
        scene.getStylesheets().add(
            MainApp.class.getResource("/styles/validator.css")
            .toExternalForm());
        stage.setScene(scene);
        stage.show();
    }

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

    private GridPane loadLoginScreen()
    {

        GridPane grid = new GridPane();
        grid.setAlignment(Pos.CENTER);
        grid.setHgap(10);
        grid.setVgap(10);
        grid.setPadding(new Insets(25, 25, 25, 25));

        Text scenetitle = new Text("Welcome");
        scenetitle.setFont(Font.font("Tahoma", FontWeight.NORMAL, 20));
        grid.add(scenetitle, 0, 0, 2, 1);

        Label userName = new Label("User Name:");
        grid.add(userName, 0, 1);

        final TextField userTextField = new TextField();
        grid.add(userTextField, 1, 1);

        Label pw = new Label("Password:");
        grid.add(pw, 0, 2);

        final PasswordField pwBox = new PasswordField();
        grid.add(pwBox, 1, 2);

        Button btn = new Button("Sign in");
        HBox hbBtn = new HBox(10);
        hbBtn.setAlignment(Pos.BOTTOM_RIGHT);
        hbBtn.getChildren().add(btn);
        grid.add(hbBtn, 1, 4);

        final Text actiontarget = new Text();
        grid.add(actiontarget, 1, 6);

        // Context Menu for error messages
        final ContextMenu usernameValidator = new ContextMenu();
        usernameValidator.getStyleClass().add("validator");

        usernameValidator.setAutoHide(false);

        final ContextMenu passValidator = new ContextMenu();
        passValidator.getStyleClass().add("validator");

        passValidator.setAutoHide(false);

        // Action on button press
        btn.setOnAction(new EventHandler<ActionEvent>()
        {

            @Override
            public void handle(ActionEvent e)
            {
                // Clearing message if any
                actiontarget.setText("");

                // Checking if the userTextField is empty
                if (userTextField.getText().equals(""))
                {

                    MenuItem cc = new MenuItem("Please enter username");
                    cc.getStyleClass().add("validator-item");

                    usernameValidator.getItems().clear();
                    usernameValidator.getItems().add(cc);
                    usernameValidator.show(userTextField, Side.RIGHT, 10, 0);
                }
                // Checking if the pwBox is empty
                if (pwBox.getText().equals(""))
                {
                    MenuItem dcc = new MenuItem("Please enter password");
                    dcc.getStyleClass().add("validator-item");

                    passValidator.getItems().clear();
                    passValidator.getItems().add(dcc);
                    passValidator.show(pwBox, Side.RIGHT, 10, 0);
                }
                // If both of the above textFields have values
                if (!pwBox.getText().equals("")
                    && !userTextField.getText().equals(""))
                {
                    actiontarget.setFill(Color.GREEN);
                    actiontarget.setText("Welcome");
                }
            }
        });

        userTextField.focusedProperty().addListener(
            new ChangeListener<Boolean>()
            {
                @Override
                public void changed(
                    ObservableValue<? extends Boolean> arg0,
                    Boolean oldPropertyValue, Boolean newPropertyValue)
                {
                    if (newPropertyValue)
                    {
                        // Clearing message if any
                        actiontarget.setText("");
                        // Hiding the error message
                        usernameValidator.hide();
                    }
                    }
            });

        pwBox.focusedProperty().addListener(new ChangeListener<Boolean>()
        {
            @Override
            public void changed(ObservableValue<? extends Boolean> arg0,
                Boolean oldPropertyValue, Boolean newPropertyValue)
            {
                if (newPropertyValue)
                {
                    // Clearing message if any
                    actiontarget.setText("");
                    // Hiding the error message
                    passValidator.hide();
                }
            }
        });
        return grid;
    }

}

validator.css

.validator {
  -fx-background-color: #006699;
  -fx-text-fill: white;
  -fx-padding: 0;
}

.validator:hover {
  -fx-background-color: #006699;
  -fx-text-fill: white;
}

.validator-item .label {
  -fx-text-fill: white;
}

.validator-item:focused .label {
  -fx-text-fill: white;
}

For example can I add event handler for the Stage?

1

1 Answers

1
votes

The simplest option would be to just switch on autohide, instead of disabling it as you have done in your code. You also wouldn't need the focus property listeners then.