下面列出了怎么用javafx.scene.control.MenuButton的API类实例代码及写法,或者点击链接到github查看源代码。
public Node getNode()
{
final TextField channels = new TextField();
channels.setEditable(false);
channels.setTooltip(new Tooltip("Channel selection"));
channelSelection.addListener((obs, oldv, newv) -> channels.setText(String.join(", ", IntStream.of(newv).boxed().map(Object::toString).toArray(String[]::new))));
MenuItem all = new MenuItem("_All");
all.setOnAction(e -> channelSelection.set(range()));
MenuItem revert = new MenuItem("_Revert");
revert.setOnAction(e -> channelSelection.set(reverted(channelSelection.get())));
MenuItem everyNth = new MenuItem("Every _Nth");
everyNth.setOnAction(e -> everyNth(numChannels.get()).ifPresent(channelSelection::set));
final MenuButton selectionButton = new MenuButton("_Select", null, all, revert, everyNth);
HBox.setHgrow(channels, Priority.ALWAYS);
return new VBox(
new Label("Channel Settings"),
new HBox(channels, selectionButton));
}
@Override
public void start(final Stage stage)
{
final MenuButton button1 = new MenuButton("Plain Button", null, new MenuItem("Item 1"), new MenuItem("Item 2"));
button1.getStyleClass().add("action_button");
final MenuItem item = new MenuItem("Action Button Item");
item.getStyleClass().add("action_button_item");
final MenuButton button2 = new MenuButton("Dark Button", null, item, new MenuItem("Plain Item"));
button2.setStyle(JFXUtil.shadedStyle(new WidgetColor(100, 0, 0)));
button2.setTextFill(Color.YELLOW);
button2.getStyleClass().add("action_button");
final HBox box = new HBox(button1, button2);
final Scene scene = new Scene(box, 800, 700);
// XXX Enable scenic view to debug styles
// ScenicView.show(scene);
JFXRepresentation.setSceneStyle(scene);
stage.setScene(scene);
stage.setTitle("MenuButtons");
stage.show();
}
/** @param menu Menu to update
* @param devices Devices for which to create menu entries
* @param device Currently selected device
* @param action Action to perform when menu item is selected
*/
private void updateDeviceMenus(final MenuButton menu, final List<String> devices, final String device, final Consumer<String> action)
{
final ToggleGroup group = new ToggleGroup();
final List<MenuItem> items = new ArrayList<>(devices.size());
for (String dev : devices)
{
final RadioMenuItem item = new RadioMenuItem(dev);
item.setToggleGroup(group);
if (dev.equals(device))
item.setSelected(true);
item.setOnAction(event -> action.accept(dev));
items.add(item);
}
menu.getItems().setAll(items);
}
private MenuButton buildSubmenu(MenuItem item) {
Menu menu = (Menu) item;
MenuButton menuButton = new MenuButton();
menuButton.setPopupSide(Side.RIGHT);
menuButton.graphicProperty().bind(menu.graphicProperty());
menuButton.textProperty().bind(menu.textProperty());
menuButton.disableProperty().bind(menu.disableProperty());
menuButton.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
menuButton.getStyleClass().addAll(item.getStyleClass());
Bindings.bindContent(menuButton.getItems(), menu.getItems());
// To determine if a TOUCH_RELEASED event happens.
// The MOUSE_ENTERED results in an unexpected behaviour on touch events.
// Event filter triggers before the handler.
menuButton.addEventFilter(TouchEvent.TOUCH_RELEASED, e -> isTouchUsed = true);
// Only when ALWAYS or SOMETIMES
if (!Priority.NEVER.equals(getSkinnable().getMenuHoverBehavior())) {
menuButton.addEventHandler(MouseEvent.MOUSE_ENTERED, e -> { // Triggers on hovering over Menu
if (isTouchUsed) {
isTouchUsed = false;
return;
}
// When ALWAYS, then trigger immediately. Else check if clicked before (case: SOMETIMES)
if (Priority.ALWAYS.equals(getSkinnable().getMenuHoverBehavior())
|| (hoveredBtn != null && hoveredBtn.isShowing())) {
menuButton.show(); // Shows the context-menu
if (hoveredBtn != null && hoveredBtn != menuButton) {
hoveredBtn.hide(); // Hides the previously hovered Button if not null and not self
}
}
hoveredBtn = menuButton; // Add the button as previously hovered
});
}
return menuButton;
}
private MenuButton buildSubmenu(MenuItem item) {
Menu menu = (Menu) item;
MenuButton menuButton = new MenuButton();
menuButton.setPopupSide(Side.RIGHT);
menuButton.graphicProperty().bind(menu.graphicProperty());
menuButton.textProperty().bind(menu.textProperty());
menuButton.disableProperty().bind(menu.disableProperty());
menuButton.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
menuButton.getStyleClass().addAll(item.getStyleClass());
Bindings.bindContent(menuButton.getItems(), menu.getItems());
// To determine if a TOUCH_RELEASED event happens.
// The MOUSE_ENTERED results in an unexpected behaviour on touch events.
// Event filter triggers before the handler.
menuButton.addEventFilter(TouchEvent.TOUCH_RELEASED, e -> isTouchUsed = true);
// Only when ALWAYS or SOMETIMES
if (!Priority.NEVER.equals(getSkinnable().getMenuHoverBehavior())) {
menuButton.addEventHandler(MouseEvent.MOUSE_ENTERED, e -> { // Triggers on hovering over Menu
if (isTouchUsed) {
isTouchUsed = false;
return;
}
// When ALWAYS, then trigger immediately. Else check if clicked before (case: SOMETIMES)
if (Priority.ALWAYS.equals(getSkinnable().getMenuHoverBehavior())
|| (hoveredBtn != null && hoveredBtn.isShowing())) {
menuButton.show(); // Shows the context-menu
if (hoveredBtn != null && hoveredBtn != menuButton) {
hoveredBtn.hide(); // Hides the previously hovered Button if not null and not self
}
}
hoveredBtn = menuButton; // Add the button as previously hovered
});
}
return menuButton;
}
public static void main(String[] args) throws IOException {
final List<String> filenames = Files.list(Paths.get(System.getProperty("user.home"))).map(Path::toAbsolutePath).map(Path::toString).collect(Collectors.toList());
Collections.sort(filenames);
PlatformImpl.startup(() -> {});
Platform.setImplicitExit(true);
Platform.runLater(() -> {
final MenuButton button = new MenuButton("Select!");
final DirectoryChooser chooser = new DirectoryChooser();
final MenuItem chooserButton = new MenuItem("Browse");
chooserButton.setOnAction(e -> chooser.showDialog(null));
button.getItems().setAll(
chooserButton,
MatchSelectionExample.menu("Recent...", System.out::println, filenames),
MatchSelectionExample.menu("Favorites...", System.out::println, filenames));
final Stage stage = new Stage();
final Scene scene = new Scene(button);
stage.setScene(scene);
stage.addEventHandler(KeyEvent.KEY_PRESSED, e -> {
if (KeyCode.ESCAPE.equals(e.getCode())) {
if (!e.isConsumed())
stage.close();
e.consume();
}
});
stage.show();
});
}
private void createToolBars(ToolBarPanel toolBarPanel) {
VLToolBar infoToolBar = new VLToolBar();
infoButton = new MenuButton(null, FXUIUtils.getIcon("info"));
infoButton.setDisable(true);
infoToolBar.add(infoButton);
toolBarPanel.add(infoToolBar);
VLToolBar clipboardToolBar = new VLToolBar();
cutButton = FXUIUtils.createButton("cut", "Remove selected text and copy to clipboard");
cutButton.setOnAction((event) -> cut());
clipboardToolBar.add(cutButton);
copyButton = FXUIUtils.createButton("copy", "Copy selected text to clipboard");
copyButton.setOnAction((event) -> copy());
clipboardToolBar.add(copyButton);
pasteButton = FXUIUtils.createButton("paste", "Paste text from clipboard");
pasteButton.setOnAction((event) -> paste());
clipboardToolBar.add(pasteButton);
toolBarPanel.add(clipboardToolBar);
VLToolBar redoToolBar = new VLToolBar();
undoButton = FXUIUtils.createButton("undo", "Undo last action");
undoButton.setOnAction((event) -> editorExecuteProc("undo"));
redoToolBar.add(undoButton);
redoButton = FXUIUtils.createButton("redo", "Redo last undone action");
redoButton.setOnAction((event) -> editorExecuteProc("redo"));
redoToolBar.add(redoButton);
toolBarPanel.add(redoToolBar);
VLToolBar searchToolBar = new VLToolBar();
Button search = FXUIUtils.createButton("search", "Search for a pattern", true);
search.setOnAction((event) -> editorExecuteProc("find"));
searchToolBar.add(search);
Button replace = FXUIUtils.createButton("replace", "Search for a pattern and replace", true);
replace.setOnAction((event) -> editorExecuteProc("replace"));
searchToolBar.add(replace);
toolBarPanel.add(searchToolBar);
VLToolBar settingsToolBar = new VLToolBar();
Button settingsButton = FXUIUtils.createButton("settings", "Modify editor settings", true);
settingsButton.setOnAction((event) -> onSettings());
settingsToolBar.add(settingsButton);
toolBarPanel.add(settingsToolBar);
}
private HBox buildBottomPane() {
sldThreshold = new Slider(0.1f, 1.0f, DEFAULT_THRESHOLD);
sldThreshold.setShowTickLabels(true);
sldThreshold.setMajorTickUnit(0.1);
sldThreshold.setBlockIncrement(0.01);
sldThreshold.setShowTickMarks(true);
sldThreshold.valueProperty().addListener(v -> update());
MenuButton mbLoadImage = new MenuButton("Load Image");
MenuItem mnLocalImage = new MenuItem("From Computer");
mbLoadImage.getItems().add(mnLocalImage);
MenuItem mnUrl = new MenuItem("Enter URL");
mnUrl.setOnAction(e -> {
Optional<String> imgUrl = AppUtils.askInputFromUser("Enter an URL", "Enter an image URL:");
AppUtils.doBlockingAsyncWork(scene, () -> {
imgUrl.ifPresent(this::checkAndLoadImage);
});
});
mnLocalImage.setOnAction(e -> {
FileChooser fc = new FileChooser();
fc.getExtensionFilters().add(new ExtensionFilter("PNG Files", "*.png"));
fc.getExtensionFilters().add(new ExtensionFilter("JPG Files", "*.jpg"));
File selectedFile = fc.showOpenDialog(sldThreshold.getScene().getWindow());
if (selectedFile != null) {
checkAndLoadImage(selectedFile);
}
});
mbLoadImage.getItems().add(mnUrl);
HBox hbBottom = new HBox(10, new Label("Threshold: "), sldThreshold, mbLoadImage);
hbBottom.setAlignment(Pos.CENTER);
return hbBottom;
}
/** Update drop-downs for devices based on current 'devices', 'x_device', 'y_devices' */
private void updateToolbar()
{
// Select the current scan in list of scan menu items
for (MenuItem scan_sel : scan_selector.getItems())
if (scan_sel.getText().endsWith("#" + reader.getScanId()))
((RadioMenuItem)scan_sel).setSelected(true);
final List<String> devices = scan_devices.get();
// Update devices for X Axis
updateDeviceMenus(x_device_selector, devices, x_device, this::selectXDevice);
int i = y_device_selectors.size();
while (i > y_devices.size())
y_device_selectors.remove(--i);
while (i < y_devices.size())
{
final MenuButton y_device_selector = new MenuButton("Value " + (1 + i++));
y_device_selector.setTooltip(new Tooltip("Select device for value axis"));
y_device_selectors.add(y_device_selector);
}
updateDeviceMenus(add_y_device, devices, null, dev -> addYDevice(dev));
// Update devices for Values
for (i=0; i<y_device_selectors.size(); ++i)
{
final int index = i;
updateDeviceMenus(y_device_selectors.get(i), devices, y_devices.get(i),
dev -> selectYDevice(index, dev));
}
final ObservableList<Node> items = toolbar.getItems();
items.remove(3, items.size());
items.addAll(y_device_selectors);
items.add(add_y_device);
if (y_devices.size() > 1)
items.add(remove_y_device);
}
public GenericBackendDialogN5 backendDialog(ExecutorService propagationExecutor) throws IOException {
final ObjectField<String, StringProperty> containerField = ObjectField.stringField(container.get(), ObjectField.SubmitOn.ENTER_PRESSED, ObjectField.SubmitOn.ENTER_PRESSED);
final TextField containerTextField = containerField.textField();
containerField.valueProperty().bindBidirectional(container);
containerTextField.setMinWidth(0);
containerTextField.setMaxWidth(Double.POSITIVE_INFINITY);
containerTextField.setPromptText("N5 container");
final EventHandler<ActionEvent> onBrowseButtonClicked = event -> {
final File initialDirectory = Optional
.ofNullable(container.get())
.map(File::new)
.filter(File::exists)
.filter(File::isDirectory)
.orElse(new File(DEFAULT_DIRECTORY));
updateFromDirectoryChooser(initialDirectory, containerTextField.getScene().getWindow());
};
final Consumer<String> processSelection = ThrowingConsumer.unchecked(selection -> {
LOG.info("Got selection {}", selection);
if (selection == null)
return;
if (isN5Container(selection)) {
container.set(null);
container.set(selection);
return;
}
updateFromDirectoryChooser(Paths.get(selection).toFile(), containerTextField.getScene().getWindow());
});
final MenuButton menuButton = BrowseRecentFavorites.menuButton("_Find", Lists.reverse(PainteraCache.readLines(this.getClass(), "recent")), FAVORITES, onBrowseButtonClicked, processSelection);
GenericBackendDialogN5 d = new GenericBackendDialogN5(containerTextField, menuButton, "N5", writerSupplier, propagationExecutor);
final String path = container.get();
updateWriterSupplier(path);
return d;
}
public GenericBackendDialogN5 backendDialog(ExecutorService propagationExecutor) {
final ObjectField<String, StringProperty> containerField = ObjectField.stringField(container.get(), ObjectField.SubmitOn.ENTER_PRESSED, ObjectField.SubmitOn.ENTER_PRESSED);
final TextField containerTextField = containerField.textField();
containerField.valueProperty().bindBidirectional(container);
containerTextField.setMinWidth(0);
containerTextField.setMaxWidth(Double.POSITIVE_INFINITY);
containerTextField.setPromptText("HDF5 file");
final Consumer<Event> onClick = event -> {
final File initialDirectory = Optional
.ofNullable(container.get())
.map(File::new)
.map(f -> f.isFile() ? f.getParentFile() : f)
.filter(File::exists)
.orElse(new File(USER_HOME));
updateFromFileChooser(initialDirectory, containerTextField.getScene().getWindow());
};
final Consumer<String> processSelection = ThrowingConsumer.unchecked(selection -> {
LOG.info("Got selection {}", selection);
if (selection == null)
return;
if (isHDF5(selection)) {
container.set(selection);
return;
}
updateFromFileChooser(new File(selection), containerTextField.getScene().getWindow());
});
final MenuButton menuButton = BrowseRecentFavorites.menuButton(
"_Find",
Lists.reverse(PainteraCache.readLines(this.getClass(), "recent")),
FAVORITES,
onClick::accept,
processSelection);
GenericBackendDialogN5 d = new GenericBackendDialogN5(containerTextField, menuButton, "N5", writerSupplier, propagationExecutor);
final String path = container.get();
if (path != null && new File(path).isFile())
writerSupplier.set(ThrowingSupplier.unchecked(() -> new N5HDF5Writer(path, 64, 64, 64)));
return d;
}
@Override
public void start(final Stage stage)
{
// Create the WebView
WebView webView = new WebView();
// Update the stage title when a new web page title is available
webView.getEngine().titleProperty().addListener(new ChangeListener<String>()
{
public void changed(ObservableValue<? extends String> ov,
final String oldvalue, final String newvalue)
{
// Set the Title of the Stage
stage.setTitle(newvalue);
}
});
// Load the Google web page
String homePageUrl = "http://www.google.com";
// Create the WebMenu
MenuButton menu = new WebMenu(webView);
// Create the Navigation Bar
NavigationBar navigationBar = new NavigationBar(webView, homePageUrl, true);
// Add the children to the Navigation Bar
navigationBar.getChildren().add(menu);
// Create the VBox
VBox root = new VBox(navigationBar, webView);
// Set the Style-properties of the VBox
root.setStyle("-fx-padding: 10;" +
"-fx-border-style: solid inside;" +
"-fx-border-width: 2;" +
"-fx-border-insets: 5;" +
"-fx-border-radius: 5;" +
"-fx-border-color: blue;");
// Create the Scene
Scene scene = new Scene(root);
// Add the Scene to the Stage
stage.setScene(scene);
// Display the Stage
stage.show();
}
@Override
public void start(final Stage stage)
{
// Create the WebView
WebView webView = new WebView();
// Update the stage title when a new web page title is available
webView.getEngine().titleProperty().addListener(new ChangeListener<String>()
{
public void changed(ObservableValue<? extends String> ov,
final String oldvalue, final String newvalue)
{
// Set the Title of the Stage
stage.setTitle(newvalue);
}
});
// Load the Google web page
String homePageUrl = "http://www.google.com";
// Create the WebMenu
MenuButton menu = new WebMenu(webView);
// Create the Browser History
BrowserHistory history = new BrowserHistory(webView);
// Create the Navigation Bar
NavigationBar navigationBar = new NavigationBar(webView, homePageUrl, true);
// Add the Children to the Navigation Bar
navigationBar.getChildren().addAll(menu,history);
// Create the VBox
VBox root = new VBox(navigationBar, webView);
// Set the Style-properties of the VBox
root.setStyle("-fx-padding: 10;" +
"-fx-border-style: solid inside;" +
"-fx-border-width: 2;" +
"-fx-border-insets: 5;" +
"-fx-border-radius: 5;" +
"-fx-border-color: blue;");
// Create the Scene
Scene scene = new Scene(root);
// Add the Scene to the Stage
stage.setScene(scene);
// Display the Stage
stage.show();
}
@Override
public void updateChanges()
{
super.updateChanges();
if (dirty_actionls.checkAndClear())
{
base = makeBaseButton();
jfx_node.getChildren().setAll(base);
}
if (dirty_representation.checkAndClear())
{
button_text = makeButtonText();
base.setText(button_text);
base.setTextFill(foreground);
base.setFont(JFXUtil.convert(model_widget.propFont().getValue()));
// If widget is not wide enough to show the label, hide menu button 'arrow'.
if (base instanceof MenuButton)
{
// Assume that desired gap and arrow occupy similar space as "__VV_".
// Check if the text exceeds the width.
final Dimension2D size = TextUtils.computeTextSize(base.getFont(), button_text + "__VV_");
final boolean hide = size.getWidth() >= model_widget.propWidth().getValue();
Styles.update(base, "hide_arrow", hide);
}
final RotationStep rotation = model_widget.propRotationStep().getValue();
final int width = model_widget.propWidth().getValue(),
height = model_widget.propHeight().getValue();
// Button 'base' is inside 'jfx_node' Pane.
// Rotation needs to be applied to the Pane,
// which then auto-sizes to the 'base' Button dimensions.
// If transforming the Button instead of the Pane,
// it will still remain sensitive to mouse clicks in the
// original, un-transformed rectangle. Unclear why.
// Applying the transformation to the Pane does not exhibit this problem.
switch (rotation)
{
case NONE:
base.setPrefSize(width, height);
if (was_ever_transformed)
jfx_node.getTransforms().clear();
break;
case NINETY:
base.setPrefSize(height, width);
jfx_node.getTransforms().setAll(new Rotate(-rotation.getAngle()),
new Translate(-height, 0));
was_ever_transformed = true;
break;
case ONEEIGHTY:
base.setPrefSize(width, height);
jfx_node.getTransforms().setAll(new Rotate(-rotation.getAngle()),
new Translate(-width, -height));
was_ever_transformed = true;
break;
case MINUS_NINETY:
base.setPrefSize(height, width);
jfx_node.getTransforms().setAll(new Rotate(-rotation.getAngle()),
new Translate(0, -width));
was_ever_transformed = true;
break;
}
}
if (dirty_enablement.checkAndClear())
{
base.setDisable(! enabled);
Styles.update(base, Styles.NOT_ENABLED, !enabled);
jfx_node.setCursor(enabled ? Cursor.DEFAULT : Cursors.NO_WRITE);
}
}
private ToolBar createToolbar()
{
final Button[] undo_redo = UndoButtons.createButtons(undo);
final ComboBox<String> zoom_levels = new ComboBox<>();
zoom_levels.getItems().addAll(JFXRepresentation.ZOOM_LEVELS);
zoom_levels.setEditable(true);
zoom_levels.setValue(JFXRepresentation.DEFAULT_ZOOM_LEVEL);
zoom_levels.setTooltip(new Tooltip(Messages.SelectZoomLevel));
zoom_levels.setPrefWidth(100.0);
// For Ctrl-Wheel zoom gesture
zoomListener zl = new zoomListener(zoom_levels);
toolkit.setZoomListener(zl);
zoom_levels.setOnAction(event ->
{
final String before = zoom_levels.getValue();
if (before == null)
return;
final String actual = requestZoom(before);
// Java 9 results in IndexOutOfBoundException
// when combo is updated within the action handler,
// so defer to another UI tick
Platform.runLater(() ->
zoom_levels.setValue(actual));
});
final MenuButton order = new MenuButton(null, null,
createMenuItem(ActionDescription.TO_BACK),
createMenuItem(ActionDescription.MOVE_UP),
createMenuItem(ActionDescription.MOVE_DOWN),
createMenuItem(ActionDescription.TO_FRONT));
order.setTooltip(new Tooltip(Messages.Order));
final MenuButton align = new MenuButton(null, null,
createMenuItem(ActionDescription.ALIGN_LEFT),
createMenuItem(ActionDescription.ALIGN_CENTER),
createMenuItem(ActionDescription.ALIGN_RIGHT),
createMenuItem(ActionDescription.ALIGN_TOP),
createMenuItem(ActionDescription.ALIGN_MIDDLE),
createMenuItem(ActionDescription.ALIGN_BOTTOM),
createMenuItem(ActionDescription.ALIGN_GRID));
align.setTooltip(new Tooltip(Messages.Align));
final MenuButton size = new MenuButton(null, null,
createMenuItem(ActionDescription.MATCH_WIDTH),
createMenuItem(ActionDescription.MATCH_HEIGHT));
size.setTooltip(new Tooltip(Messages.Size));
final MenuButton dist = new MenuButton(null, null,
createMenuItem(ActionDescription.DIST_HORIZ),
createMenuItem(ActionDescription.DIST_VERT));
dist.setTooltip(new Tooltip(Messages.Distribute));
// Use the first item as the icon for the drop-down...
try
{
order.setGraphic(ImageCache.getImageView(ActionDescription.TO_BACK.getIconResourcePath()));
align.setGraphic(ImageCache.getImageView(ActionDescription.ALIGN_LEFT.getIconResourcePath()));
size.setGraphic(ImageCache.getImageView(ActionDescription.MATCH_WIDTH.getIconResourcePath()));
dist.setGraphic(ImageCache.getImageView(ActionDescription.DIST_HORIZ.getIconResourcePath()));
}
catch (Exception ex)
{
logger.log(Level.WARNING, "Cannot load icon", ex);
}
return new ToolBar(
grid = createToggleButton(ActionDescription.ENABLE_GRID),
snap = createToggleButton(ActionDescription.ENABLE_SNAP),
coords = createToggleButton(ActionDescription.ENABLE_COORDS),
new Separator(),
order,
align,
size,
dist,
new Separator(),
undo_redo[0],
undo_redo[1],
new Separator(),
zoom_levels);
}
private ToolBar createToolbar() {
final ToolBar toolBar = new ToolBar();
ImageView homeIcon = ImageCache.getImageView(ImageCache.class, "/icons/home.png");
homeIcon.setFitHeight(16.0);
homeIcon.setFitWidth(16.0);
home_display_button = new Button(null, homeIcon);
home_display_button.setTooltip(new Tooltip(Messages.HomeTT));
toolBar.getItems().add(home_display_button);
final TopResources homeResource = TopResources.parse(Preferences.home_display);
home_display_button.setOnAction(event -> openResource(homeResource.getResource(0), false));
top_resources_button = new MenuButton(null, ImageCache.getImageView(getClass(), "/icons/fldr_obj.png"));
top_resources_button.setTooltip(new Tooltip(Messages.TopResources));
top_resources_button.setDisable(true);
toolBar.getItems().add(top_resources_button);
layout_menu_button = new MenuButton(null, ImageCache.getImageView(getClass(), "/icons/layouts.png"));
layout_menu_button.setTooltip(new Tooltip(Messages.LayoutTT));
toolBar.getItems().add(layout_menu_button);
// Contributed Entries
ToolbarEntryService.getInstance().listToolbarEntries().forEach((entry) -> {
final AtomicBoolean open_new = new AtomicBoolean();
// If entry has icon, use that with name as tool tip.
// Otherwise use the label as button text.
final Button button = new Button();
final Image icon = entry.getIcon();
if (icon == null)
button.setText(entry.getName());
else
{
button.setGraphic(new ImageView(icon));
button.setTooltip(new Tooltip(entry.getName()));
}
// Want to handle button presses with 'Control' in different way,
// but action event does not carry key modifier information.
// -> Add separate event filter to remember the 'Control' state.
button.addEventFilter(MouseEvent.MOUSE_PRESSED, event -> {
open_new.set(event.isControlDown());
// Still allow the button to react by 'arming' it
button.arm();
});
button.setOnAction((event) -> {
try {
// Future<?> future = executor.submit(entry.getActions());
if (open_new.get()) { // Invoke with new stage
final Window existing = DockPane.getActiveDockPane().getScene().getWindow();
final Stage new_stage = new Stage();
DockStage.configureStage(new_stage);
entry.call();
// Position near but not exactly on top of existing stage
new_stage.setX(existing.getX() + 10.0);
new_stage.setY(existing.getY() + 10.0);
new_stage.show();
} else
entry.call();
} catch (Exception ex) {
logger.log(Level.WARNING, "Error invoking toolbar " + entry.getName(), ex);
}
});
toolBar.getItems().add(button);
});
toolBar.setPrefWidth(600);
return toolBar;
}