Michael Berry
Michael Berry

Reputation: 72379

JavaFX 2 custom popup pane

The JavaFX 2 colour picker has a button that pops up a colour chooser pane like so:

JavaFX 2 colour picker

I'd like to do something similar, in that I'd like a custom pane to pop up when the button is clicked on and disappear when something else is clicked (in my case, a few image thumbnails). What would be the best way of achieving this? Should I use a ContextMenu and add a pane to a MenuItem somehow, or is there something else I should look at?

Upvotes: 20

Views: 23915

Answers (2)

I'm a little late, but I can recommend you use FxPopup, an API of my creation, this adds XML code to the root of your application, making it responsive immediately. In version v1.1.0 I don't add the option to add overlay, so you'll have to create them, in the following versions I'll add the option

You can make some like this:

Rectangle overlay;
FxPopup fxPopup;
ImageView imageView;

    @FXML
    public void initialize() {
        fxPopup = new FxPopup();

        // Image example
        imageView = new ImageView("https://th.bing.com/th/id/OIP.TnnO-9C6THhBBCzOhTe7mQHaFj?rs=1&pid=ImgDetMain");

        // Making a Overlay
        overlay = new Rectangle();
        overlay.setFill(Color.BLACK);
        overlay.setOpacity(0.3);

        // Remove image and overlay when the overlay is clicked
        overlay.setOnMouseClicked(event -> {
            MasterUtils.remove(imageView);
            MasterUtils.remove(overlay);
        });
    }

    @FXML
    protected void onThumbnails() {
        fxPopup.show(overlay, Pos.CENTER);

        // Bind Overlay with root, for max size
        overlay.widthProperty().bind(((Pane) MasterUtils.getRoot()).widthProperty());
        overlay.heightProperty().bind(((Pane) MasterUtils.getRoot()).heightProperty());

        fxPopup.show(imageView, Pos.CENTER);
    }

Upvotes: 1

jewelsea
jewelsea

Reputation: 159566

It's kind of difficult to do well with the current JavaFX 2.2 API.

Here are some options.


Use a MenuButton with a graphic set in it's MenuItem

This is the approach taken in Button with popup showed below's executable sample code.

wizpopup


Use a PopupControl

Take a look at how the ColorPicker does this in it's code.

ColorPicker extends PopupControl. You could do this, but not all of the API required to build your own PopupControl is currently public. So, for JavaFX 2.2, you would have to rely on internal com.sun classes which are deprecated and will be replaced by public javafx.scene.control classes in JDK8.


Use a ContextMenu

So, I think your idea to "use a ContextMenu and add a pane to a MenuItem" is probably the best approach for now. You should be able to do this by using a CustomMenuItem or setting a graphic on a normal MenuItem. The ContextMenu has nice relative positioning logic. A ContextMenu can also be triggered by a MenuButton.


Use a Custom Dialog

To do this, display a transparent stage at a location relative to the node.

There is some sample code to get you started which I have temporarily linked here. The sample code does relative positioning to the sides of the main window, but you could update it to perform positioning relative to the sides of a given node (like the ContextMenu's show method).


Use a Glass Pane

To do this, create a StackPane as your root of your main window. Place your main content pane as the first node in the StackPane and then create a Group as the second node in the stackpane, so that it will layer over the top of the main content. Normally, the top group contains nothing, but when you want to show your popup, place it in the top group and translate it to a location relative to the appropriate node in your main content.

You could look at how the anchor nodes in this demo are used to see how this might be adaptable to your context.


Is there a relevant update for this for JavaFX8?

There is not much difference of relevance for Java 8, in general the options are as outlined in this post based on Java 2.2 functionality. Java 8 does add Dialog and Alert functionality, but those are more targeted at use of dialogs with borders, titles and buttons rather than the kind of functionality desired in the question. Perhaps you might be able to start from the Dialog class and heavily customize it to get something close to what is needed, but you are probably better off starting from a blank stage or PopupControl instead.

Upvotes: 34

Related Questions