Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

implementing Toggle in javafx ComboBox

MuzibJun 16 2017 — edited Jun 19 2017

While using SolidWorks 2013, I came across this type of ComboBox which also operates as a ToggleButton:

img1.pngimg2.png

I was wondering if I can somehow create such Toggle-ComboBox.

After a little research, I found that I have 3 options:

  1. Using a SplitMenuButton.

    img3.png

    This option has numerous propblems, such as, it doesn't have a value property.

    That creates a problem because the caption never changes with the action of MenuItems.

  2. Using a ComboBox setting the property 'editable' to true, which looks like this:

img4.png

   But it's problem is that, in the 'Button cell', there is a TextField, which I really don't want.
  1. Making my own custom control for this.

Now, is there anything I can do with the first two options? That will be better. If not, what will be the best way to create a custom one?

This post has been answered by bouye-JavaNet on Jun 18 2017
Jump to Answer

Comments

bouye-JavaNet
Answer

It's not that hard to do it:

public class Main extends Application {

    @Override

    public void start(final Stage primaryStage) {

        // Creates items for menu button.

        final ToggleGroup toogleGroup = new ToggleGroup();

        final MenuItem[] menus = IntStream.range(0, 10)

                .mapToObj(index -> {

                    final RadioMenuItem menuItem = new RadioMenuItem();

                    menuItem.setText(String.format("Radio #%d", index + 1));

                    menuItem.setToggleGroup(toogleGroup);

                    menuItem.setOnAction(event -> System.out.printf("Action -> %s%n", menuItem.getText()));

                    return menuItem;

                })

                .toArray(MenuItem[]::new);

        toogleGroup.getToggles().get(0).setSelected(true);

        // Creates menu button.

        final SplitMenuButton splitMenuButton = new SplitMenuButton();

        // Forward action to selected item when button is clicked.

        // Works ok but logs warnings when the selected toggle is briefly null when the selection changes.

//        splitMenuButton.onActionProperty().bind(Bindings.select(toogleGroup.selectedToggleProperty(), "onAction"));

        // Works ok without warnings.

        splitMenuButton.setOnAction(event -> {

            Optional.ofNullable((RadioMenuItem) toogleGroup.getSelectedToggle())

                    .ifPresent(menuItem -> {

                        Optional.ofNullable(menuItem.getOnAction())

                                .ifPresent(eventHandler -> eventHandler.handle(event));

                    });

        });

        // Bind item's text to button.

        splitMenuButton.textProperty().bind(new StringBinding() {

            {

                bind(toogleGroup.selectedToggleProperty());

            }

            @Override

            public void dispose() {

                unbind(toogleGroup.selectedToggleProperty());

                super.dispose();

            }

            @Override

            protected String computeValue() {

                final RadioMenuItem menuItem = (RadioMenuItem) toogleGroup.getSelectedToggle();

                String result = (menuItem == null) ? null : menuItem.getText();

                return result;

            }

        });

        // Bind item's graphic to button.

        splitMenuButton.graphicProperty().bind(new ObjectBinding<Node>() {

            {

                bind(toogleGroup.selectedToggleProperty());

            }

            @Override

            public void dispose() {

                unbind(toogleGroup.selectedToggleProperty());

                super.dispose();

            }

            @Override

            protected Node computeValue() {

                final RadioMenuItem menuItem = (RadioMenuItem) toogleGroup.getSelectedToggle();

                final Node result = null;

                // Find a way to duplicate graphic here.

                // final Node result = (menuItem == null) ? null : duplicateGraphic(menuItem.getGraphic());

                return result;

            }

        });

        splitMenuButton.getItems().setAll(menus);

        final StackPane root = new StackPane();

        root.getChildren().add(splitMenuButton);

        final Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("Test");

        primaryStage.setScene(scene);

        primaryStage.show();

    }

    public static void main(final String[] args) {

        launch(args);

    }

}

Marked as Answer by Muzib · Sep 27 2020
Muzib

Wow! works fine. I appreciate it. Thanks a lot.

@

1 - 2
Locked Post
New comments cannot be posted to this locked post.

Post Details

Locked on Jul 17 2017
Added on Jun 16 2017
2 comments
470 views