Forum Stats

  • 3,839,332 Users
  • 2,262,484 Discussions
  • 7,900,936 Comments

Discussions

implementing Toggle in javafx ComboBox

Muzib
Muzib Member Posts: 10
edited Jun 19, 2017 7:05AM in JavaFX 2.0 and Later

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.

3.    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?

Tagged:
Muzib

Best Answer

  • bouye-JavaNet
    bouye-JavaNet Member Posts: 394 Silver Badge
    edited Jun 18, 2017 5:53PM 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);    }}
    Muzib

Answers

  • bouye-JavaNet
    bouye-JavaNet Member Posts: 394 Silver Badge
    edited Jun 18, 2017 5:53PM 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);    }}
    Muzib
  • Muzib
    Muzib Member Posts: 10
    edited Jun 19, 2017 7:05AM

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

This discussion has been closed.