Aspirant
Aspirant

Reputation: 1954

JavaFX2: MODAL capability to a context menu

Is there a way to add MODAL capability to a context menu?

My code is below:

package snippet;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.ColorPicker;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;

public class ContextMenuSample extends Application
{
public static void main(String[] args)
{
    launch(args);
}

@Override
public void start(Stage stage)
{
    stage.setTitle("ContextMenuSample");

    Scene scene = new Scene(new Group(), 450, 250);

    Label toLabel = new Label("To: ");

    TextField notification = new TextField();

    final ContextMenu contextMenu = new ContextMenu();
    contextMenu.setAutoHide(false);
    contextMenu.setOnShowing(new EventHandler<WindowEvent>()
    {
        public void handle(WindowEvent e)
        {
            System.out.println("showing the context menu");
        }
    });
    contextMenu.setOnShown(new EventHandler<WindowEvent>()
    {
        public void handle(WindowEvent e)
        {
            System.out.println("context menu has been shown");
        }
    });
    MenuItem closeItem = new MenuItem("Close");
    closeItem.setOnAction(new EventHandler<ActionEvent>()
    {
        public void handle(ActionEvent e)
        {
            contextMenu.hide();
        }
    });
    MenuItem colorItem = new MenuItem("Choose", new ColorPicker());
    colorItem.setOnAction(new EventHandler<ActionEvent>()
    {
        public void handle(ActionEvent e)
        {
            System.out.println("Preferences");
        }
    });


    GridPane contextGridPane = new GridPane();

    Pane pane = new Pane();
    pane.getChildren().add(contextGridPane);


    contextMenu.getItems().addAll(colorItem, deleteItem// , subsystem1,
                                                       // radioItem
        );
    toLabel.setContextMenu(contextMenu);
    GridPane grid = new GridPane();
    grid.setVgap(4);
    grid.setHgap(10);
    grid.setPadding(new Insets(5, 5, 5, 5));
    grid.add(toLabel, 0, 0);
    grid.add(notification, 1, 0);
    grid.add(new ColorPicker(), 2, 0);
    Group root = (Group) scene.getRoot();
    root.getChildren().add(grid);
    stage.setScene(scene);
    stage.show();
}
}

When the user clicks on the label "To", a context menu appears. I wish to have modal capability for this context menu such that the user is not able to do anything else on the application unless some operation is performed on the context menu. Also, when the context menu is active, the user should not be able to click anywhere else on the application.

Regards,

Upvotes: 1

Views: 302

Answers (1)

thatsIch
thatsIch

Reputation: 848

The easiest solution would be to call another Stage and set its modality with initModality before you show the stage. You probably want to use Modality.APPLICATION_MODEL as far as I understood you.

Here is a small example derived from yours (btw your code was not even runnable, it had errors)

public class ContextMenuSample extends Application
{
    public static void main(String[] args)
    {
        launch(args);
    }

    @Override
    public void start(final Stage stageOne)
    {
        final Stage stageTwo = new Stage();
        stageTwo.initModality(Modality.APPLICATION_MODAL);

        final Pane layoutOne = new HBox(10);
        Pane layoutTwo = new HBox(10);

        Label labelOne = new Label("click");
        Label labelTwo = new Label("other click");

        labelOne.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                stageTwo.show();
            }
        });

        labelTwo.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                stageTwo.close();
            }
        });

        Scene sceneOne = new Scene(layoutOne);
        Scene sceneTwo = new Scene(layoutTwo);

        layoutOne.getChildren().add(labelOne);
        layoutTwo.getChildren().add(labelTwo);

        stageOne.setScene(sceneOne);
        stageTwo.setScene(sceneTwo);

        stageOne.show();
    }
}

Upvotes: 1

Related Questions