package javaapplication10; import java.util.Arrays; import javafx.application.Application; import javafx.beans.property.BooleanProperty; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.event.ActionEvent; import javafx.event.Event; import javafx.event.EventHandler; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.ComboBox; import javafx.scene.control.Label; import javafx.scene.control.Menu; import javafx.scene.control.MenuBar; import javafx.scene.control.MenuItem; import javafx.scene.control.Separator; import javafx.scene.control.TextArea; import javafx.scene.control.TextField; import javafx.scene.control.ToggleButton; import javafx.scene.input.KeyCombination; import javafx.scene.layout.HBox; import javafx.scene.layout.Pane; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import javafx.scene.shape.Rectangle; import javafx.stage.Modality; import javafx.stage.Stage; public class JavaApplication10 extends Application { public final static String TEST_PANE_ID = "TestPane"; public final static String CLEAR_BTN_ID = "Clear"; public final static String RESET_BTN_ID = "Reset"; public final static String USESYSTEM_BTN_ID = "Use system menu bar"; public final static String USESYSTEMCSS_BTN_ID = "Use system menu bar (using CSS)"; public final static String ADD_SINGLE_AT_POS_BTN_ID = "Add Menu"; public final static String REMOVE_SINGLE_AT_POS_BTN_ID = "Remove Menu"; public final static String REMOVE_POS_EDIT_ID = "Remove at pos"; public final static String ADD_POS_EDIT_ID = "Add at pos"; public final static String MENU_STR = "Menu "; public final static int MENUS_NUM = 3; public final static int MENUS_DEPTH = 3; public final static String CLEAR_EVENT_ID = "Clear Events"; private ShortcutGenerator shortcutGenerator = new ShortcutGenerator(); private boolean useTwoMenuBars = false; Stage stage; public static void main(String[] args) { launch(args); } protected Scene getScene() { Application.Parameters parameters = getParameters(); useTwoMenuBars = parameters.getUnnamed().contains("useTwoMenuBars"); return new MenuBarAppScene("", stage); } @Override public void start(Stage stage) throws Exception { this.stage = stage; stage.setScene(getScene()); stage.show(); } public class MenuBarAppScene extends Scene { private String sceneTag = ""; private int childCount; private int childShift; private Stage parentStage; public MenuBarAppScene(String aTag, Stage aStage) { super(new VBox(20d)); sceneTag = aTag; //prefix to distinguish different stages parentStage = aStage; //stage on which current scene is rendered //Add controls to create model windows with different modality states HBox controlsContainer = new HBox(5d); if (useTwoMenuBars) { controlsContainer.getChildren().addAll( new MenuControls(sceneTag + "#1"), new MenuControls(sceneTag + "#2")); } else { controlsContainer.getChildren().add(new MenuControls(sceneTag)); } ((VBox) getRoot()).getChildren().add(controlsContainer); //Add controls to create modal windows with diffent modalities HBox createChildWindows = new HBox(5d); Label lblChildMod = new Label("Child's modality: "); final ComboBox cmbModalities = new ComboBox(); cmbModalities.getItems().addAll(Arrays.asList(Modality.values())); cmbModalities.setValue(Modality.NONE); Button btnCreateChild = new Button("Create child"); btnCreateChild.setOnAction(new EventHandler() { public void handle(ActionEvent t) { Stage newStage = new Stage(); newStage.initModality(cmbModalities.getValue()); newStage.setTitle("Modality: " + cmbModalities.getValue().name()); newStage.initOwner(parentStage); newStage.setScene(new MenuBarAppScene(getModalWindowPrefix(), newStage)); childShift += 100; newStage.setX(parentStage.getX() + childShift); newStage.showAndWait(); } }); if (useTwoMenuBars) { createChildWindows.getChildren().addAll(lblChildMod, cmbModalities, btnCreateChild); ((VBox) getRoot()).getChildren().add(createChildWindows); } //If this scene belongs to the main stage if (useTwoMenuBars && parentStage == stage) { //Add button to create new non-modal window final Button btnCloneWindow = new Button("Clone window"); btnCloneWindow.setOnAction(new EventHandler() { public void handle(ActionEvent t) { Stage newStage = new Stage(); newStage.setTitle("Second window"); newStage.setX(parentStage.getX() + 200); newStage.setScene(new MenuBarAppScene("Clone", newStage)); newStage.show(); //no more stages btnCloneWindow.setOnAction(null); } }); ((VBox) getRoot()).getChildren().addAll(new Separator(), btnCloneWindow); } } /** * This method generates prefix for modal window which helps to * distinguish it from other modal window in case there are many * * @return modal window prefix */ private String getModalWindowPrefix() { StringBuilder stringBuilder = new StringBuilder(sceneTag); if (!sceneTag.equals("")) { stringBuilder.append("->"); } stringBuilder.append("Ch#"); stringBuilder.append(++childCount); return stringBuilder.toString(); } } private class MenuControls extends VBox { private MenuBar menuBar; private Label lastVisited; private TextArea eventLog; private String prefix; private ShortcutGenerator initialShortcutGen; public MenuControls(String prefix) { setSpacing(5d); this.prefix = prefix; this.initialShortcutGen = shortcutGenerator.clone(); menuBar = new MenuBar(); lastVisited = new Label(); eventLog = new TextArea(); Pane test_pane = new Pane(); test_pane.setPrefSize(600, 300); test_pane.setMaxSize(600, 300); getChildren().add(test_pane); Label lblTitle = new Label("Panel " + prefix); test_pane.getChildren().add(menuBar); reset(); Button clear_buton = new Button(CLEAR_BTN_ID); clear_buton.setOnAction(new EventHandler() { public void handle(ActionEvent t) { menuBar.getMenus().clear(); } }); Button reset_buton = new Button(RESET_BTN_ID); reset_buton.setOnAction(new EventHandler() { public void handle(ActionEvent t) { reset(); } }); final TextField add_position = new TextField("0"); Button add_buton_pos = new Button(ADD_SINGLE_AT_POS_BTN_ID); add_buton_pos.setOnAction(new EventHandler() { public void handle(ActionEvent t) { int pos = Integer.valueOf(add_position.getText()); if (pos > menuBar.getMenus().size()) { pos = menuBar.getMenus().size(); } menuBar.getMenus().add(pos, new BarItem(MENU_STR + menuBar.getMenus().size(), MENUS_DEPTH, eventLog, lastVisited)); } }); final Label add_label = new Label("at"); HBox add_position_box = new HBox(5); add_position_box.getChildren().addAll(add_buton_pos, add_label, add_position); final TextField remove_position = new TextField("0"); Button remove_buton = new Button(REMOVE_SINGLE_AT_POS_BTN_ID); remove_buton.setOnAction(new EventHandler() { public void handle(ActionEvent t) { if (menuBar.getMenus().size() > 0) { int pos = Integer.valueOf(remove_position.getText()); if (pos > menuBar.getMenus().size() - 1) { pos = menuBar.getMenus().size() - 1; } menuBar.getMenus().remove(pos); } } }); final Label remove_label = new Label("at"); HBox remove_position_box = new HBox(5); remove_position_box.getChildren().addAll(remove_buton, remove_label, remove_position); ToggleButton use_system = new ToggleButton(USESYSTEM_BTN_ID); use_system.setId(USESYSTEM_BTN_ID); use_system.selectedProperty().addListener(new ChangeListener() { public void changed(ObservableValue ov, Boolean t, Boolean t1) { menuBar.setUseSystemMenuBar(t1); } }); ToggleButton use_system_css = new ToggleButton(USESYSTEMCSS_BTN_ID); use_system_css.setId(USESYSTEMCSS_BTN_ID); use_system_css.selectedProperty().addListener(new ChangeListener() { public void changed(ObservableValue ov, Boolean t, Boolean t1) { menuBar.setStyle("-fx-use-system-menu-bar: " + (t1 ? "true" : "false") + ";"); } }); ToggleButton disableSomeMenusButton = new ToggleButton("Some menus disable"); final BooleanProperty mainDisablingProperty = new SimpleBooleanProperty(false); menuBar.getMenus().get(1).disableProperty().bind(mainDisablingProperty); menuBar.getMenus().get(0).getItems().get(0).disableProperty().bind(mainDisablingProperty); menuBar.getMenus().get(2).getItems().get(2).disableProperty().bind(mainDisablingProperty); disableSomeMenusButton.selectedProperty().addListener(new ChangeListener() { public void changed(ObservableValue ov, Boolean t, Boolean t1) { mainDisablingProperty.setValue(t1); } }); ToggleButton setGraphicsToggle = new ToggleButton("Set graphics"); setGraphicsToggle.selectedProperty().addListener(new ChangeListener() { public void changed(ObservableValue ov, Boolean t, Boolean t1) { if (t1) { menuBar.getMenus().get(1).setGraphic(new Rectangle(10, 10, Color.BLUE)); menuBar.getMenus().get(0).getItems().get(0).setGraphic(new Rectangle(10, 10, Color.RED)); menuBar.getMenus().get(2).getItems().get(2).setGraphic(new Rectangle(10, 10, Color.GREEN)); } else { menuBar.getMenus().get(1).setGraphic(null); menuBar.getMenus().get(0).getItems().get(0).setGraphic(null); menuBar.getMenus().get(2).getItems().get(2).setGraphic(null); } } }); Button renamingButton = new Button("Rename"); renamingButton.setOnAction(new EventHandler() { public void handle(ActionEvent t) { menuBar.getMenus().get(1).setText("Renamed " + menuBar.getMenus().get(1).getText()); menuBar.getMenus().get(0).getItems().get(0).setText("Renamed " + menuBar.getMenus().get(0).getItems().get(0).getText()); menuBar.getMenus().get(2).getItems().get(2).setText("Renamed " + menuBar.getMenus().get(2).getItems().get(2).getText()); } }); ToggleButton disableMenuBarButton = new ToggleButton("MenuBar disable"); disableMenuBarButton.selectedProperty().addListener(new ChangeListener() { public void changed(ObservableValue ov, Boolean t, Boolean t1) { menuBar.setDisable(t1); } }); HBox last_selected_box = new HBox(5); last_selected_box.getChildren().add(new Label("Last selected item:")); last_selected_box.getChildren().add(lastVisited); HBox events_box = new HBox(5); Button clear = new Button(CLEAR_EVENT_ID); clear.setOnAction(new EventHandler() { public void handle(ActionEvent t) { eventLog.clear(); } }); events_box.getChildren().add(eventLog); events_box.getChildren().add(clear); VBox controls = new VBox(5); getChildren().add(controls); controls.getChildren().addAll(lblTitle, clear_buton, reset_buton, add_position_box, remove_position_box, use_system, use_system_css, disableMenuBarButton, disableSomeMenusButton, setGraphicsToggle, renamingButton, last_selected_box, events_box); } private void reset() { //restore shortcut generator to reproduce exactly the same menu shortcuts shortcutGenerator = initialShortcutGen.clone(); menuBar.getMenus().clear(); for (int i = 0; i < MENUS_NUM; i++) { menuBar.getMenus().add(new BarItem(prefix + " " + MENU_STR + i, MENUS_DEPTH, eventLog, lastVisited)); } } } private class BarItem extends Menu { private TextArea log; private Label lastSelected; public BarItem(String str, int depth, TextArea log, Label lastSelected) { super(str); this.log = log; this.lastSelected = lastSelected; addSubMenu(this, depth - 1); setLog(this, this.log); } private void addSubMenu(MenuItem root, int level) { for (int i = 0; i < MENUS_NUM; i++) { final MenuItem item; if (level > 0) { item = new Menu(root.getText() + " SubMenu " + i); setLog((Menu) item, this.log); } else { item = new MenuItem(root.getText() + " MenuItem " + i); } item.setOnAction(new EventHandler() { public void handle(ActionEvent t) { lastSelected.setText(item.getText()); } }); ((Menu) root).getItems().add(item); if (level > 0) { addSubMenu(item, level - 1); } else { item.setAccelerator(shortcutGenerator.getShortcut()); } } } protected void setLog(final Menu menu, final TextArea log) { menu.setOnAction(new EventHandler() { public void handle(ActionEvent t) { log.appendText("OnAction event from " + menu.getText() + "\n"); log.end(); } }); menu.setOnHiding(new EventHandler() { public void handle(Event t) { log.appendText("OnHiding event from " + menu.getText() + "\n"); log.end(); } }); menu.setOnHidden(new EventHandler() { public void handle(Event t) { log.appendText("OnHidden event from " + menu.getText() + "\n"); log.end(); } }); menu.setOnShowing(new EventHandler() { public void handle(Event t) { log.appendText("OnShowing event from " + menu.getText() + "\n"); log.end(); } }); menu.setOnShown(new EventHandler() { public void handle(Event t) { log.appendText("OnShown event from " + menu.getText() + "\n"); log.end(); } }); } } private class ShortcutGenerator { private char c; private int mask; private String mods[] = new String[]{"ctrl", "alt", "shift"}; public ShortcutGenerator() { c = 'A'; mask = 0; } public ShortcutGenerator(char c, int mask) { this.c = c; this.mask = mask; } public KeyCombination getShortcut() { StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < mods.length; i++) { if (((mask >> i) & 1) != 0) { stringBuilder.append(mods[i]).append("+"); } } stringBuilder.append(c); if (++c > 'Z') { c = 'A'; mask++; } KeyCombination kk = KeyCombination.keyCombination(stringBuilder.toString()); return kk; } @Override public ShortcutGenerator clone() { return new ShortcutGenerator(c, mask); } } }