I have looked at a few JavaFX classes related to menu, but I could not find what I want. I want to implement something that works like a MenuBar, except that I want it to open its menu on hover, not on click. While I can definitely build something from scratch on my own, it would be a waste of time if there is already something that allows me to do something similar to that. Anyone knows how do I do that?
Well it is possible to make it if you use the lookup(). You can easily take the container holding the Menus and then apply on them the setOnMouseEntered() or setOnMouseExited() to catch mouse events on each Menu.
Here is an example :
import javafx.application.Application;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
BorderPane mainPane = new BorderPane();
MenuBar menuBar = new MenuBar();
Menu editMenu = new Menu("File");
MenuItem fileMenuItem1 = new MenuItem("Item 1");
MenuItem fileMenuItem2 = new MenuItem("Item 2");
MenuItem fileMenuItem3 = new MenuItem("Item 3");
editMenu.getItems().addAll(fileMenuItem1, fileMenuItem2, fileMenuItem3);
Menu fileMenu = new Menu("Edit");
MenuItem fileMenu1 = new MenuItem("Item 1");
MenuItem fileMenu2 = new MenuItem("Item 2");
MenuItem fileMenu3 = new MenuItem("Item 3");
fileMenu.getItems().addAll(fileMenu1, fileMenu2, fileMenu3);
menuBar.getMenus().addAll(editMenu, fileMenu);
mainPane.setTop(menuBar);
Scene scene = new Scene(mainPane, 300, 300);
Stage stage = new Stage();
stage.setScene(scene);
stage.show();
// Find menubar HBox holding the menus
HBox container = (HBox) menuBar.lookup("HBox");
for(int i = 0 ; i < container.getChildren().size() ; i++) {
Node parentNode = container.getChildren().get(i);
Menu menu = menuBar.getMenus().get(i);
parentNode.setOnMouseMoved(e->{
menu.show();
});
}
}
public static void main(String[] args) {
launch(args);
}
}
You might wonder why i use the setOnMouseMoved instead of setOnMouseEntered. Well that's because the setOnMouseEntered creates a strange behavior while moving the mouse between menus and the usage of setOnMouseMoved fix it.
In addition in case you wondering how did I know to use the lookup("HBox") the truth is my first attempt was System.out.println( menuBar.lookupAll("*")); which gave me the current informations :
[MenuBar#5e57a6ce[styleClass=menu-bar], HBox#13ccf856[styleClass=container], MenuBarSkin$MenuBarButton[id=null, styleClass=menu-button menu]'File', MenuButtonSkinBase$MenuLabeledImpl#25917f7f[styleClass=label]'File', Text[text="File", x=0.0, y=0.0, alignment=LEFT, origin=BASELINE, boundsType=LOGICAL_VERTICAL_CENTER, font=Font[name=System Regular, family=System, style=Regular, size=12.0], fontSmoothingType=LCD, fill=0x333333ff], StackPane#c341eae[styleClass=arrow-button], StackPane#7b8501c0[styleClass=arrow], MenuBarSkin$MenuBarButton[id=null, styleClass=menu-button menu]'Edit', MenuButtonSkinBase$MenuLabeledImpl#4d8224b7[styleClass=label]'Edit', Text[text="Edit", x=0.0, y=0.0, alignment=LEFT, origin=BASELINE, boundsType=LOGICAL_VERTICAL_CENTER, font=Font[name=System Regular, family=System, style=Regular, size=12.0], fontSmoothingType=LCD, fill=0x333333ff], StackPane#3d75fcac[styleClass=arrow-button], StackPane#71f02eed[styleClass=arrow]]
I think you are looking for class javafx.scene.control.ContextMenu and the method show(Node anchor, double screenX, double screenY)
Related
I am new to JavaFX
I wrote this code however, I dont know how to Display the Menu Bar in all my Scenes. Also I would like to create/fill my scenes with the Layout in my HelloApplication (however thats another issue).
I have a controller, for setting the Stage and launching it.
My MenuBar is in the class MenuLeiste, but I would like it to appear in my Credits class aswell. Im very sorry for the lack of comments and the Layout of this comment.
public class HelloApplication extends Application {
public class Main {
public static void main(String[] args) {
launch(args);
}
}
#Override
public void start(Stage primaryStage) throws Exception {
//set window as primaryStage
Stage window = primaryStage;
//Layout of MenuLeiste is put in l1 and setted as scene1
MenuLeiste l1 = new MenuLeiste();
//menuscene gets its objects fromsceneViewMenu
Scene menuscene = new Scene(l1.sceneViewMenu());
window.setScene(menuscene);
window.setHeight(600);
window.setWidth(800);
window.setTitle("Game Title");
window.show();
}
}
My MenuLeiste class
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class MenuLeiste {
public VBox sceneViewMenu() {
MenuBar menuBar = new MenuBar();
VBox menuBox = new VBox(menuBar);
Menu dataMenu = new Menu("Data");
MenuItem exitItem = new MenuItem("Exit");
exitItem.setOnAction(e -> System.exit(0));
Menu extrasMenu = new Menu("Extras");
MenuItem creditsItem = new MenuItem("Credits");
creditsItem.setOnAction(e -> {
Credits c = new Credits();
Scene scene3 = new Scene(c.sceneView3());
Stage window = (Stage) menuBox.getScene().getWindow();
window.setScene(scene3);
});
extrasMenu.getItems().addAll(creditsItem);
dataMenu.getItems().addAll( exitItem);
menuBar.getMenus().addAll(dataMenu,extrasMenu);
//the scenes layout is saved in layout1
VBox layout1 = new VBox(20);
layout1.getChildren().addAll(menuBox);
return layout1;
}
}
My Credits Class
package view;
import javafx.scene.Scene;`
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;`
public class Credits {
public VBox sceneView3()
{
Label label = new Label("Thanks");
Button backButton = new Button("Back");
backButton.setOnAction(e -> {
MenuLeiste l1 = new MenuLeiste();
Scene menuscene = new Scene(l1.sceneViewMenu());
Stage window = (Stage) backButton.getScene().getWindow();
window.setScene(menuscene);
});
VBox layout1 = new VBox(20);
layout1.getChildren().addAll(label, backButton);
return layout1;
}
}
When you want a node, or a group of nodes, to exist between different "scenes", often the best solution is to not replace the Scene. Instead, you'll want to modify the nodes displayed in the current scene. For example, in your case, you could have a BorderPane as the root of the scene with the MenuBar set as the top node. Then you replace the center node when you want to change the "view".
Here's a minimal runnable example demonstrating this concept. It makes use of "callbacks" to modify the center node of the BorderPane, while using the same MenuBar instance throughout. Though note the example only consists of views. If you have a backing model (i.e., data, business logic, etc.), you'll want to modify the code so you can pass it around. Also, if you write your application similarly to this example, it might be prudent to have all the views implement a common interface in a real application.
I don't have a separate "view class" for the menu bar, but that doesn't mean you can't have one (might even be better that way).
Main.java:
import java.util.function.Consumer;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
var root = new BorderPane();
root.setTop(createMenuBar(root::setCenter));
root.setCenter(new TitleView().getNode());
primaryStage.setScene(new Scene(root, 600, 400));
primaryStage.setTitle("Demo");
primaryStage.show();
}
private MenuBar createMenuBar(Consumer<Node> onUpdateView) {
var exitItem = new MenuItem("Exit");
exitItem.setOnAction(e -> Platform.exit());
var creditsItem = new MenuItem("Credits");
creditsItem.setOnAction(e -> {
e.consume();
var view = new CreditsView();
view.setOnGoBack(() -> onUpdateView.accept(new TitleView().getNode()));
onUpdateView.accept(view.getNode());
});
return new MenuBar(
new Menu("File", null, exitItem),
new Menu("Extras", null, creditsItem)
);
}
}
TitleView.java:
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
public class TitleView {
private Node node;
public Node getNode() {
if (node == null) {
node = new StackPane(new Label("Welcome!"));
}
return node;
}
}
CreditsView.java:
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
public class CreditsView {
private Runnable onGoBack;
private Node node;
public Node getNode() {
if (node == null) {
var stack = new StackPane();
stack.setPadding(new Insets(10));
var label = new Label("Credits View");
stack.getChildren().add(label);
var goBackBtn = new Button("Go back");
goBackBtn.setOnAction(e -> {
e.consume();
if (onGoBack != null) {
onGoBack.run();
}
});
stack.getChildren().add(goBackBtn);
StackPane.setAlignment(goBackBtn, Pos.TOP_LEFT);
node = stack;
}
return node;
}
public void setOnGoBack(Runnable action) {
onGoBack = action;
}
}
Here is some basic code that should be easy for a beginner to understand.
The main layout and the potential views to be displayed within it are created upfront.
A menu bar is placed at the top of the border pane in the main layout.
Menu items can be used to switch between views by setting the node to be currently displayed in the center of the border pane.
The existing views are reused rather than being recreated on each navigation.
You could not store references to existing views and create new views on each navigation if preferred.
The views themselves are just nodes, so the example could easily be adapted to use FXML because the output of the FXML loader is also a node. The same goes for anything else which may generate a node to be used as a view in this fashion.
Operation
The scene is initially displayed and the user clicks on the "View" menu to show the list of available views.
The user selects the "View Two" menu item and the second view is displayed. The application menu remains visible and can be used for future operations.
Sample Code
import javafx.application.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
public class ViewSwitcherApp extends Application {
private BorderPane layout;
private final Node viewOne = new ViewOne();
private final Node viewTwo = new ViewTwo();
#Override
public void start(Stage stage) throws Exception {
// View menu
MenuItem viewOneMenuItem = new MenuItem("View One");
viewOneMenuItem.setOnAction(e -> setView(viewOne));
MenuItem viewTwoMenuItem = new MenuItem("View Two");
viewTwoMenuItem.setOnAction(e -> setView(viewTwo));
Menu viewMenu = new Menu(
"View", null,
viewOneMenuItem, viewTwoMenuItem
);
// File menu
MenuItem exitMenuItem = new MenuItem("Exit");
exitMenuItem.setOnAction(e -> Platform.exit());
Menu fileMenu = new Menu(
"File", null,
exitMenuItem
);
MenuBar menuBar = new MenuBar(
fileMenu, viewMenu
);
menuBar.setMinSize(MenuBar.USE_PREF_SIZE, MenuBar.USE_PREF_SIZE);
// Layout scene
layout = new BorderPane();
layout.setTop(menuBar);
setView(viewOne);
stage.setScene(
new Scene(layout, 300, 200)
);
stage.show();
}
private void setView(Node view) {
layout.setCenter(view);
}
public static void main(String[] args) {
launch(args);
}
}
class ViewOne extends StackPane {
public ViewOne() {
setStyle("-fx-background-color: lightblue; -fx-font-size: 30px;");
getChildren().add(new Label("View One"));
}
}
class ViewTwo extends StackPane {
public ViewTwo() {
setStyle("-fx-background-color: cornsilk; -fx-font-size: 30px;");
getChildren().add(new Label("View Two"));
}
}
I have a javafx application that displays content inside a scrollpane. This content includes a TabPane. Inside the tabpane, there is a VBox containing widgets that can change height based on user interaction, especially:
table view where more rows are shown
TitledPane that are expanded.
When this happens, the application does not resize as expected. I understand the problem is that the tabpane does not expand to match its expanded content.
However, the layout would correctly update if I resized the application window, or just selected another tab and then come back in the original tab.
So I believe what is missing is just "triggering" some re-layout. However, I could not manage it by triggering a requestLayout when the tab content is resized. I tried forcing the tabpane minHeight and maxHeight then the tab content is resized also, but it does not work.
See below a sample program that shows the problem (this is javafx 8, but I believe the issue has not been fixed since then)
import javafx.application.Application;
import javafx.beans.property.ReadOnlyDoubleProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.stage.Stage;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.SingleSelectionModel;
import javafx.scene.layout.VBox;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TitledPane;
import javafx.scene.control.TabPane;
import javafx.scene.control.Tab;
public class TitledPaneBench extends Application {
#Override
public void start(Stage stage) throws Exception {
ScrollPane pane = new ScrollPane();
VBox box = new VBox();
box.getChildren().add(new Label("Test"));
box.getChildren().add(new Label("Test2"));
box.getChildren().add(new Label("Test3"));
VBox cbox = new VBox();
cbox.getChildren().add(new Label("Test ABC"));
cbox.getChildren().add(new Label("Test CDE"));
cbox.getChildren().add(new Label("Test DEF"));
cbox.getChildren().add(new Label("Test EFG"));
TitledPane titledpane = new TitledPane("Test collapsible",cbox);
titledpane.setExpanded(false);
box.getChildren().add(titledpane);
box.getChildren().add(new Label("Test4"));
TabPane tabpane = new TabPane();
Tab tab1 = new Tab();
tab1.setText("First tab");
tab1.setContent(box);
Tab tab2 = new Tab();
tab2.setText("Faire Valoir");
tab2.setContent(new Label("Choucroute"));
tabpane.getTabs().add(tab1);
tabpane.getTabs().add(tab2);
box.heightProperty().addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> arg0, Number arg1, Number arg2) {
System.err.println("Height changed "+arg1+" <- "+arg2);
SingleSelectionModel<Tab> selectionmodel = tabpane.getSelectionModel();
box.requestLayout();
tabpane.requestLayout();
}
});
pane.setContent(tabpane);
stage.setScene(new Scene(pane));
stage.show();
}
public static void main(String args[]) {
TitledPaneBench tb = new TitledPaneBench();
tb.launch(args);
}
}
Take a look at this I moved some things around to clean it up and make it easier for myself to read and understand the line you are looking for is titledpane.setOnMouseClicked(event -> tabpane.requestLayout());
let me know if I misunderstood the problem I can update the answer unless someone else beats me to it
public class Main extends Application {
#Override
public void start(Stage stage) {
VBox cbox = new VBox();
cbox.getChildren().addAll(
new Label("Test ABC"),
new Label("Test CDE"),
new Label("Test DEF"),
new Label("Test EFG")
);
TabPane tabpane = new TabPane();
TitledPane titledpane = new TitledPane("Test collapsible",cbox);
titledpane.setExpanded(false);
//The line below should solve the issue
titledpane.setOnMouseClicked(event -> tabpane.requestLayout());
VBox box = new VBox();
box.getChildren().addAll(
new Label("Test"),
new Label("Test2"),
new Label("Test3"),
titledpane,
new Label("Test4")
);
tabpane.getTabs().addAll(
new Tab("First tab",box),
new Tab("Faire Valoir",new Label("Choucroute"))
);
box.heightProperty().addListener((arg0, arg1, arg2) -> {
System.err.println("Height changed "+arg1+" <- "+arg2);
SingleSelectionModel<Tab> selectionmodel = tabpane.getSelectionModel();//Unused
});
ScrollPane scrollPane = new ScrollPane(tabpane);
stage.setScene(new Scene(scrollPane));
stage.show();
}
}
vbox2.setPadding(new Insets(3));
vbox2.setSpacing(3);
vbox2.getChildren().addAll( browser1,browser);
HBox.setHgrow(vbox2, Priority.ALWAYS);
hbox.setPadding(new Insets(20));
// StackPane.setMargin(hbox, new Insets(20));
hbox.getChildren().addAll(vbox, vbox2);
root.getChildren().add(hbox);
Scene scene = new Scene(root, 500, 300); // the stack pane is the root node
//scene.setCursor(Cursor.CROSSHAIR);
MenuBar menuBar = new MenuBar();
Menu menu = new Menu("Window");
menu.getItems().add(new MenuItem("browser"));
menu.getItems().add(new MenuItem("img"));
menuBar.getMenus().add(menu);
menuBar.prefWidthProperty().bind(primaryStage.widthProperty());
BorderPane borderPane = new BorderPane();
borderPane.prefHeightProperty().bind(scene.heightProperty());
borderPane.prefWidthProperty().bind(scene.widthProperty());
borderPane.setTop(menuBar);
root.getChildren().add(borderPane);
primaryStage.setScene(scene);
primaryStage.show();
}
here is the code part where is im adding menu bar with border pane but its hang my application as im not able to login or do anythng and i had to add child window also for reference im attaching the image
This is a very basic and minimal example of handling views in the center of a BorderPane by MenuItems:
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.BorderPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
BorderPane root = new BorderPane();
// create the menu bar with a menu and its items
MenuBar menuBar = new MenuBar();
Menu mainMenu = new Menu("Window");
MenuItem browserItem = new MenuItem("browser");
MenuItem imageItem = new MenuItem("image");
MenuItem closeItem = new MenuItem("exit");
// create some different contents for the center of the border pane
Label imagePlaceHolder = new Label("IMAGE TO BE SHOWN");
WebView browser = new WebView();
WebEngine browserEngine = browser.getEngine();
// set the actions for the different items
closeItem.setOnAction(action -> {
System.exit(0);
});
imageItem.setOnAction(action -> {
root.setCenter(imagePlaceHolder);
});
browserItem.setOnAction(action -> {
root.setCenter(browser);
browserEngine.load("http://www.google.com");
});
// add items to the menu, then the menu to the menu bar
mainMenu.getItems().addAll(closeItem, browserItem, imageItem);
menuBar.getMenus().add(mainMenu);
// set the scene
Scene scene = new Scene(root,400,400);
root.setTop(menuBar);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
I hope it helps…
EDIT
I just saw your newest edit… In case you really need different windows (scenes or stages), the approach will get more complex. Readers have to get more information about the different windows (like how you create them, handle their contents and more).
I have a JavaFX application that has various TextField widgets in the main frame. I have a MenuBar that includes the MenuItem objects "Copy" and "Paste" like a standard production application would have. Since any or none of the various TextField objects could be selected at any given time, it seems easier to just hardcode a "Ctrl+C" or "Ctrl+V" key press in the setOnAction events of the "Copy" and "Paste" MenuItem objects rather than use a Clipboard object and loop iterating through all TextFields to find the highlighted text (if any).
Is there a way to hardcode this key press action in Java? I looked into the KeyCombination class but it does not actually trigger the action described by the given key combination.
I think by "Since any or none of the various TextField objects could be selected at any given time" you are referring to which (if any) text field has the keyboard focus.
You can easily get this information from the scene: just do
Node focusOwner = scene.getFocusOwner();
if (focusOwner instanceof TextField) {
TextField textField = (TextField) focusOwner ;
String selectedText = textField.getSelectedText();
// ...
}
Note also that TextInputControl defines a copy() method that copies the selected text to the system clipboard. (Similarly, there's a paste() method too.) So you can leverage those to make the functionality easy.
Here's a SSCCE:
import javafx.application.Application;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextField;
import javafx.scene.control.TextInputControl;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class FocusMenuTest extends Application {
#Override
public void start(Stage primaryStage) {
BorderPane root = new BorderPane();
VBox textFields = new VBox(5, new TextField("One"), new TextField("Two"), new TextField("Three"));
MenuBar menuBar = new MenuBar();
Menu edit = new Menu("Edit");
MenuItem copy = new MenuItem("Copy");
copy.setOnAction(e -> {
Node focusOwner = menuBar.getScene().getFocusOwner();
if (focusOwner instanceof TextInputControl) {
((TextInputControl)focusOwner).copy();
}
});
MenuItem paste = new MenuItem("Paste");
paste.setOnAction(e -> {
Node focusOwner = menuBar.getScene().getFocusOwner();
if (focusOwner instanceof TextInputControl) {
((TextInputControl)focusOwner).paste();
}
});
menuBar.getMenus().add(edit);
edit.getItems().addAll(copy, paste);
root.setCenter(textFields);
root.setTop(menuBar);
Scene scene = new Scene(root, 400, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I am working on a project using JavaFX. I have included FontAwesome in my project to avoid using images for simple icons. I created the following function in a constants class that generates an HBox with an icon and text that will be called in the setGraphic(Node node). The function is as follows:
public static HBox iconText(String icon, String text) {
return ConstantsClass.iconText(icon, text, 5);
}
public static HBox iconText(String icon, String text, int spacing) {
HBox box = new HBox(spacing);
Label iconLabel = new Label(icon);
iconLabel.setFont(ConstantsClass.fontAwesome);
Label textLabel = new Label(text);
box.getChildren().addAll(iconLabel, textLabel);
return box;
}
The method works perfectly on buttons, such as having a back button with an arrow icon. However it does not seem to work on MenuItems.
I have a menu bar at the top of my application with Menus in them, and MenuItems in those. I tried the same process with a "settings" MenuItem, but the text does not appear unless the cursor is over the item.
MenuItem settings = new MenuItem();
settings.setGraphic(ConstantsClass.iconText(FontAwesome.COG, "Settings")); //Obscuring name of Constants Class
This code has the following results:
When the user just clicks on the menu drop down
When the user hovers over the Menu Item
How can I make the MenuItem always show the icon and text?
It's kind of weird it looks like a bug. If there is no label in the graphic, the graphic seems to display OK (for instance a rectangle seems to work correctly as a graphic). My guess is it is some kind of mess-up in the interaction between the CSS styling rules and the menu skin implementation.
A workaround is to use a snapshot, but that somehow makes the thing being snapshot slightly bold in appearance.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.control.*;
import javafx.scene.image.*;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class MenuDisplay extends Application {
public void start(Stage stage) throws Exception {
Label label = new Label("(*)");
label.setStyle("-fx-background-color: null;");
Scene dummyScene = new Scene(label, Color.TRANSPARENT);
SnapshotParameters params = new SnapshotParameters();
params.setFill(Color.TRANSPARENT);
Image snapshot = label.snapshot(params, null);
ImageView imageView = new ImageView(snapshot);
Menu menu = new Menu("Choices");
menu.getItems().addAll(
new MenuItem("Broken Label Graphic", new Label("(*)")),
new MenuItem("OK Rect", new Rectangle(16, 16, Color.FORESTGREEN)),
new MenuItem("Fixed Snapshot", imageView)
);
MenuBar menuBar = new MenuBar(menu);
Scene scene = new Scene(
new VBox(menuBar), 100, 100
);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Maybe somebody else can come up with a better workaround (or fix).