A JavaFX library for creating dynamic and configurable toolbars and menu items using a command pattern.
- Declarative UI: Define toolbar and menu items using enums and builders.
 - Command Pattern: Decouple UI components from their actions using a command pattern.
 - SVG Support: Use SVG icons for your UI components1.
 - State Management: Manage the state of your application and reflect it in the UI.
 - Extensible: Easily extend the library with your own commands and UI components.
 - Cross-Java: Compiled for Java 8 compatible with 11+.
 
This project uses Maven for dependency management. To include it in your project, add the following to your pom.xml:
<dependency>
    <groupId>com.intechcore.scomponents</groupId>
    <artifactId>menu-tree-builder</artifactId>
    <version>1.5.0</version>
</dependency>The following is a basic example of how to use the library to create a toolbar with a few buttons and a submenu (see full example in the test part).
Create an enum that implements IIcon and IIconSourceConfig to define the icons for your toolbar items.
public enum Icons implements IIcon, IIconSourceConfig {
    BRICK_WALL("brick-wall"),
    MENU("menu"),
    // ... other icons
    private final String fileName;
    private final IIconBuilder iconBuilder = new HevergirodFxsvqimageSvgIconBuilder();
    Icons(String fileName) {
        this.fileName = fileName;
    }
    @Override
    public String[] getData() {
        return new String[] {"/icons/" + this.fileName + ".svg"};
    }
    @Override
    public double getLeftOffset() {
        return 0;
    }
    @Override
    public IIconBuilder getBuilder() {
        return this.iconBuilder;
    }
}Create enums that implement IToolboxCommandConfig to define the menu items and submenus.
public enum ExampleMenuItem implements IToolboxCommandConfig {
    CONFIRMATION_STATE(Icons.BRICK_WALL, ControlType.BUTTON),
    ALERT_INFO(Icons.INFO, ControlType.BUTTON),
    // ... other menu items
}
public enum ExampleSubmenuItem implements IToolboxCommandConfig {
    ALERT_MENU(Icons.MENU, ControlType.SUBMENU),
    // ... other submenus
}Create classes that extend AbstractCommand to define the actions for your menu items.
public class AlertStateCommand extends AbstractCommand<AppState> {
    // ... implementation
}
public class ChangeStateCommand extends AbstractCommand<AppState> {
    // ... implementation
}Create a class that implements ICommandFactory to create and store your commands.
public class CommandFactory implements ICommandFactory<AppState> {
    // ... implementation
}Use the MenuItemFactoryBuilder to build the toolbar from your defined menu items and command factory.
public class Example extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception {
        IEventManager eventManager = new EventManager();
        AppState service = new AppState();
        MenuItemFactoryBuilder factoryBuilder = new MenuItemFactoryBuilder(
                CompletableFuture.completedFuture(eventManager))
                .setIconMapper(Util.buildDefaultIconMapper(Icons.values(), Icons.class))
                .setShortLabel(true)
                .setHideSubmenuOnClick(true)
                .setIconScaleFactor(1);
        List<Node> menuButtons = factoryBuilder.buildMenuItems(
                new CommandFactory(service, primaryStage),
                Stream.of(
                        ExampleMenuItem.CONFIRMATION_STATE,
                        ExampleSubmenuItem.ALERT_MENU.add(
                                ExampleMenuItem.ALERT_INFO,
                                ExampleMenuItem.ALERT_WARNING,
                                ExampleSubmenuItem.SQUARE_MENU.add(
                                        ExampleMenuItem.ALERT_ERROR,
                                        ExampleMenuItem.TOGGLE1_STATE_1,
                                        ExampleMenuItem.TOGGLE1_STATE_2,
                                        ExampleMenuItem.TOGGLE1_STATE_3
                                )
                        )
                ));
        ToolBar toolBar = new ToolBar(menuButtons.toArray(new Node[0]));
        Scene scene = new Scene(new VBox(toolBar), 1500, 750);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}- common-core
 - SLF4J
 - Apache Batik
 - fxsvgimage
 - JUnit 5 (for testing)
 - OpenJFX
 
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Footnotes
- 
The com.github.hervegirod.fxsvgimage is using. This library for now (version 1.4) cannot draw SVG file with missing L or l command after move command, so you can fix the SVG from scratch to success drawing ↩