I am trying to implement a menu. This is my code :
Menu menuFile1 = new Menu("ADD");
Menu menuFile2 = new Menu("EDIT");
Menu menuFile3 = new Menu("VIEW");
Menu menuFile4 = new Menu("HELP");
How can I put some space between each menu (that is between ADD,EDIT,VIEW and HELP) ?
Answer
Space around menus is controlled by padding (see the Region css guide).
For example:
menu.setStyle("-fx-padding: 5 10 8 10;");
sets the padding around the menu to 5 pixels on the top, 10 pixels on the right, 8 pixels on the bottom and 10 pixels on the left.
Sample
The following is a bit overcomplicated for a code sample to demonstrate this effect, but you could run it to see the effect of varying padding values.
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.StringExpression;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class SpacedOut extends Application {
#Override
public void start(final Stage stage) {
MenuBar menuBar = createMenuBar();
VBox controlPane = createControlPane(menuBar);
VBox layout = new VBox(10,
menuBar,
controlPane
);
VBox.setVgrow(controlPane, Priority.ALWAYS);
stage.setScene(new Scene(layout, 400, 200));
stage.show();
}
private MenuBar createMenuBar() {
MenuBar menuBar = new MenuBar();
menuBar.getMenus().addAll(
new Menu("ADD"),
new Menu("EDIT"),
new Menu("VIEW"),
new Menu("HELP")
);
return menuBar;
}
private VBox createControlPane(MenuBar menuBar) {
CheckBox useCustomPadding = new CheckBox("Use Custom Padding");
useCustomPadding.setSelected(false);
Slider padAmount = new Slider(0, 30, 15);
padAmount.setShowTickMarks(true);
padAmount.setShowTickLabels(true);
padAmount.setMajorTickUnit(10);
padAmount.setMaxWidth(200);
padAmount.disableProperty().bind(
useCustomPadding.selectedProperty().not()
);
VBox contentPane = new VBox(10,
useCustomPadding,
padAmount
);
contentPane.setPadding(new Insets(10));
StringExpression paddingExpression = Bindings.concat(
"-fx-padding: ", padAmount.valueProperty(), "px;"
);
menuBar.getMenus().forEach(
menu -> menu.styleProperty().bind(
Bindings
.when(useCustomPadding.selectedProperty())
.then(paddingExpression)
.otherwise("")
)
);
return contentPane;
}
public static void main(String[] args) {
launch(args);
}
}
With the setStyle() Method you can pass one or more css styles in one string.
Like menuFile1.setStyle("-fx-border-color: red; -fx-effect: dropshadow( one-pass-box , red , 10,0.5,0,0 );");
Alternatively you could put your style information inside a css file and add it to the Scene through.
Scene somescene = new Scene(root)
somescene.getStylesheets().add("your.css");
See the css reference of Java FX 2 or this tutorial.
Related
I have a collection of buttons:
VBox menuButtons = new VBox();
menuButtons.getChildren().addAll(addButton, editButton, exitButton);
I want to add some spacing between these buttons, without using a CSS style sheet. I think there should be a way to do this.
setPadding(); is for the Buttons in the VBox.
setMargin(); should be for the VBox itself. But I didn't find a way for the spacing between the buttons.
I'm glad for any ideas. :)
VBox supports spacing out of the box:
VBox menuButtons = new VBox(5);
or
menuButtons.setSpacing(5);
Just call setSpacing method and pass some value.
Example with HBox (it's same for VBox):
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.scene.layout.HBoxBuilder;
import javafx.stage.Stage;
public class SpacingDemo extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
stage.setTitle("Spacing demo");
Button btnSave = new Button("Save");
Button btnDelete = new Button("Delete");
HBox hBox = HBoxBuilder.create()
.spacing(30.0) //In case you are using HBoxBuilder
.padding(new Insets(5, 5, 5, 5))
.children(btnSave, btnDelete)
.build();
hBox.setSpacing(30.0); //In your case
stage.setScene(new Scene(hBox, 320, 240));
stage.show();
}
}
And this is how it looks:
Without of spacing:
With spacing:
If you're using FXML, use the spacing attribute:
<VBox spacing="5" />
As others have mentioned you can use setSpacing().
However, you can also use setMargin(), it is not for the pane (or box in your words), it is for individual Nodes. setPadding() method is for the pane itself. In fact, setMargin() takes a node as a parameter so you can guess what it's for.
For example:
HBox pane = new HBox();
Button buttonOK = new Button("OK");
Button buttonCancel = new Button("Cancel");
/************************************************/
pane.setMargin(buttonOK, new Insets(0, 10, 0, 0)); //This is where you should be looking at.
/************************************************/
pane.setPadding(new Insets(25));
pane.getChildren().addAll(buttonOK, buttonCancel);
Scene scene = new Scene(pane);
primaryStage.setTitle("Stage Title");
primaryStage.setScene(scene);
primaryStage.show();
You could get the same result if you replaced that line with
pane.setSpacing(10);
If you have several nodes that should be spaced, setSpacing() method is far more convenient because you need to call setMargin() for each individual node and that would be ridiculous. However, setMargin() is what you need if you need margins(duh) around a node that you can determine how much to each side because setSpacing() methods places spaces only in between nodes, not between the node and the edges of the window.
The same effect as the setSpacing method can also be achieved via css:
VBox {
-fx-spacing: 8;
}
I need to display one or more stage(s) within a TabPane by clicking on a button, such as the picture below
My target is to have a situation similar to JInternalFrame in Swing: how to accomplish this?
I am not able to add stage as children to the tab pane.
If this is not possible, what could be other solutions? I would like to have SplitPanes on the stage.
Thanks
PS I am using Win7, NetBeans 7.4 Beta (Build 201307092200), SceneBuilder 1.1
Edit: here is how it looks after some VFXWindows css changes
There's one thing worth notice: I have had to add a node ( in my case an HBox with prefSize(0,0), otherwise I can't move o resize the first window plotted, only the first one.
As last, I can't find a way to set windows full screen (maximize).
Here I put an example of windows from jfxtras inside of Tabs, I just modify the example.
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.stage.Stage;
import jfxtras.labs.scene.control.window.CloseIcon;
import jfxtras.labs.scene.control.window.MinimizeIcon;
import jfxtras.labs.scene.control.window.Window;
public class WindowInTab extends Application {
private static int counter = 1;
private void init(Stage primaryStage) {
TabPane tabPane = new TabPane();
Tab tab = generateTab("Windows...");
Tab anotherTab = generateTab("More Windows");
tabPane.getTabs().addAll(tab, anotherTab);
primaryStage.setResizable(true);
primaryStage.setScene(new Scene(tabPane, 600, 500));
}
private Tab generateTab(String tabName) {
Tab tab = new Tab(tabName);
final Group root = new Group();
tab.setContent(root);
Button button = new Button("Add more windows");
root.getChildren().addAll(button);
button.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent arg0) {
// create a window with title "My Window"
Window w = new Window("My Window#"+counter);
// set the window position to 10,10 (coordinates inside canvas)
w.setLayoutX(10);
w.setLayoutY(10);
// define the initial window size
w.setPrefSize(300, 200);
// either to the left
w.getLeftIcons().add(new CloseIcon(w));
// .. or to the right
w.getRightIcons().add(new MinimizeIcon(w));
// add some content
w.getContentPane().getChildren().add(new Label("Content... \nof the window#"+counter++));
// add the window to the canvas
root.getChildren().add(w);
}
});
return tab;
}
public double getSampleWidth() {return 600;}
public double getSampleHeight() {return 500;}
#Override
public void start(Stage primaryStage) throws Exception {
init(primaryStage);
primaryStage.show();
}
public static void main(String[] args) {launch(args);}
}
I don't know if this was exactly what you were looking for. Hope it helps!
I'm making a MenuBar, and I wan't the functionality to press a Menu like: "File" and then execute a action. Such like opening an other fxml, or an example where some output is written.
I want the functionality of a MenuItem (lie "About") in a Menu like "File".
package model;
import static java.lang.System.out;
import javafx.application.Application;
import javafx.beans.property.ReadOnlyDoubleProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.geometry.Side;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
/**
* Example of creating menus in JavaFX.
*
* #author Dustin
*/
public class JavaFxMenus extends Application
{
/**
* Build menu bar with included menus for this demonstration.
*
* #param menuWidthProperty Width to be bound to menu bar width.
* #return Menu Bar with menus included.
*/
private MenuBar buildMenuBarWithMenus(final ReadOnlyDoubleProperty menuWidthProperty)
{
final MenuBar menuBar = new MenuBar();
// Prepare left-most 'File' drop-down menu
final Menu fileMenu = new Menu("File");
menuBar.getMenus().add(fileMenu);
//menuBar.getOnMouseClicked().handle(this);
// Prepare 'Examples' drop-down menu
final Menu examplesMenu = new Menu("JavaFX 2.0 Examples");
examplesMenu.getItems().add(new MenuItem("Text Example"));
examplesMenu.getItems().add(new MenuItem("Objects Example"));
examplesMenu.getItems().add(new MenuItem("Animation Example"));
menuBar.getMenus().add(examplesMenu);
// Prepare 'Help' drop-down menu
final Menu helpMenu = new Menu("Help");
helpMenu.setOnAction(null);
final MenuItem searchMenuItem = new MenuItem("Search");
searchMenuItem.setDisable(true);
helpMenu.getItems().add(searchMenuItem);
final MenuItem onlineManualMenuItem = new MenuItem("Online Manual");
onlineManualMenuItem.setVisible(false);
helpMenu.getItems().add(onlineManualMenuItem);
helpMenu.getItems().add(new SeparatorMenuItem());
final MenuItem aboutMenuItem =
MenuItemBuilder.create()
.text("About")
.onAction(
new EventHandler<ActionEvent>()
{
#Override public void handle(ActionEvent e)
{
out.println("You clicked on About!");
}
})
.accelerator(
new KeyCodeCombination(
KeyCode.A, KeyCombination.CONTROL_DOWN))
.build();
helpMenu.getItems().add(aboutMenuItem);
menuBar.getMenus().add(helpMenu);
// bind width of menu bar to width of associated stage
menuBar.prefWidthProperty().bind(menuWidthProperty);
return menuBar;
}
/**
* Start of JavaFX application demonstrating menu support.
*
* #param stage Primary stage.
*/
#Override
public void start(final Stage stage)
{
stage.setTitle("Creating Menus with JavaFX 2.0");
final Group rootGroup = new Group();
final Scene scene = new Scene(rootGroup, 800, 400, Color.WHEAT);
final MenuBar menuBar = buildMenuBarWithMenus(stage.widthProperty());
rootGroup.getChildren().add(menuBar);
stage.setScene(scene);
stage.show();
}
/**
* Main executable function for running examples.
*
* #param arguments Command-line arguments: none expected.
*/
public static void main(final String[] arguments)
{
Application.launch(arguments);
}
}
AFAIK, A Menu, if has not any added submenu or Menuitems, does not fire events neither on click, on shown nor on hide. However the workaround is to set its graphic where this graphic node will handle mouse clicks for example,
Label menuLabel = new Label("File");
menuLabel.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
Stage myDialog = new Stage();
myDialog.initModality(Modality.WINDOW_MODAL);
Scene myDialogScene = new Scene(VBoxBuilder.create()
.children(new Text("Hello! it's My Dialog."))
.alignment(Pos.CENTER)
.padding(new Insets(10))
.build());
myDialog.setScene(myDialogScene);
myDialog.show();
}
});
Menu fileMenuButton = new Menu();
fileMenuButton.setGraphic(menuLabel);
menuBar.getMenus().add(fileMenuButton);
A drawback of this approach is that the label do not cover all spaces of the menu resulting clicking on edges of menu is not triggering the mouse event. See this by uncommenting menuLabel.setStyle line above. But this can be resolved by playing with CSS styles I think.
Code is partially taken from Create Dialog using Stage. You can also load an FXML file into the myDialog stage using the FXMLLoader. There are lots of examples about it on the net.
Recently i had the same problem, this is what i did
#FXML private Menu myMenu;
#Override
public void initialize(URL url, ResourceBundle rb) {
myMenu.setGraphic(
ButtonBuilder.create()
.text("btnText")
.onAction(new EventHandler<ActionEvent>(){
#Override public void handle(ActionEvent t) {
//TODO
} })
.build()
);
}
Combining with the answer from our friend #Dota2, i built a helper class to trigger the Menu's onAction(Menu menu) event even if it does not have any MenuItem inside. Here is the static helper method:
public static void onAction(Menu menu)
{
final MenuItem menuItem = new MenuItem();
menu.getItems().add(menuItem);
menu.addEventHandler(Menu.ON_SHOWN, event -> menu.hide());
menu.addEventHandler(Menu.ON_SHOWING, event -> menu.fire());
}
Then you call:
YourHelperClass.onAction(myMenu);
And ready! I hope this helps.
Recently I faced the same issue, this was my way out:
I had a menuItem in the menu, which was to behave as if the menuItem is clicked (in your case File menu). So what you can do is have a menuItem Dummy_menuItem
final Menu fileMenu = new Menu("File");
fileMenu.getItems().add(new MenuItem("Dummy_menuItem"));
menuBar.getMenus().add(fileMenu);
and then on click of File menu, fire the Dummy_menuItem menuItem or any functionality you wish to have. To identify which menu should have this property, I used numberOfMenuItems to get the number of menuItems in the menus in menubar
if (numberOfMenuItems == 1) {
menu.showingProperty().addListener(
(observableValue, oldValue, newValue) -> {
if (newValue) {
// the first menuItem is triggered
menu.getItems().get(0).fire();
}
}
);
}
the outcome is that the Dummy_menuItem is triggered without the context displaying the menuItem on click of File menu or any menu that has one menuItem. So it appears as if you clicked the File menu and were redirected to another page or whatever.
Hope this helps!!
I think you can't allow any action on the main Menu label.
However, you can create a stackpane, and fill it with text and a menu bar.
I have a Pane (test_) as the center child of a border pane. The child fills its area and grows when the window is stretched as expected.
Now I scale test_. Normally it would be centered in its area, but I don't want that, so I translate it back to the upper-left corner of its area.
But now when I stretch the widow it pulls test_ away from the upper-left corner of its area. Can anyone explain why this happens? The sample below incorporates a slider that scale's test_.
Thank you.
package fxuicontrols;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Bounds;
import javafx.scene.Scene;
import javafx.scene.control.Slider;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class ScaleTest
extends Application
implements ChangeListener<Number>
{
private final Pane test_ = new Pane();
public static void main(String[] args)
{
launch();
}
#Override
public void start(Stage stage) throws Exception
{
test_.setStyle( "-fx-background-color: blue;" );
Text text = new Text( "Upper left corner" );
text.setFill( Color.WHITE );
text.relocate( 0, 0 );
test_.getChildren().add( text );
final Slider scaler = new Slider( .25, 1, 1 );
scaler.valueProperty().addListener( this );
test_.scaleXProperty().bind( scaler.valueProperty() );
test_.scaleYProperty().bind( scaler.valueProperty() );
BorderPane root = new BorderPane();
root.setPrefSize( 250, 250 );
root.setCenter( test_ );
root.setBottom( scaler );
stage.setScene( new Scene( root ) );
stage.show();
}
#Override
public void
changed( ObservableValue<? extends Number> oVal,
Number oldNm,
Number newNum
)
{
double scale = newNum.doubleValue();
Bounds bounds = test_.getLayoutBounds();
double width = bounds.getWidth();
double height = bounds.getHeight();
test_.setTranslateX( (scale * width - width) / 2 );
test_.setTranslateY( (scale * height - height) / 2 );
}
}
The reason your solution goes awry when the Scene is resized is because Panes are resizable nodes, so the layoutbounds of the Pane is changing as the Pane is being resized, but you aren't taking that into account in your translation calculations.
The following directly uses Scale and Translate transforms to avoid any resizing related issues. Does this sample code do what you want?
import javafx.application.Application;
import javafx.beans.value.*;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.control.Slider;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
import javafx.scene.transform.*;
import javafx.stage.Stage;
// demonstrates scaling a test pane with content in it.
// slide the slider at the bottom of the scene around to shrink and grow the content.
public class ScaleTest extends Application {
public static void main(String[] args) { launch(); }
#Override public void start(Stage stage) throws Exception {
// create a test pane for scaling.
Pane testPane = new Pane();
// make the test pane background a different color if you want to see the extent of the pane.
testPane.setStyle("-fx-background-color: blue;");
// create some text content to place in the test pane.
Text text = new Text("Upper left corner");
text.setStyle("-fx-font-size: 30px;");
text.setFill(Color.WHITE);
text.setTextOrigin(VPos.TOP);
testPane.getChildren().add(text);
Scale scaleTransform = new Scale();
testPane.getTransforms().addAll(scaleTransform, new Translate(0, 0));
// slider to scale the test pane.
final Slider scaler = new Slider(.25, 3, 1);
scaleTransform.xProperty().bind(scaler.valueProperty());
scaleTransform.yProperty().bind(scaler.valueProperty());
// stackpane added to pad out empty space when testPane is scaled small.
// stackpane also clips the zoomed content when it gets larger than it's standard layout.
final StackPane stack = new StackPane();
stack.getChildren().addAll(testPane);
StackPane.setAlignment(testPane, Pos.TOP_LEFT);
stack.setStyle("-fx-background-color: blue;");
final Rectangle clip = new Rectangle();
testPane.layoutBoundsProperty().addListener(new ChangeListener<Bounds>() {
#Override public void changed(ObservableValue<? extends Bounds> observable, Bounds oldBounds, Bounds bounds) {
clip.setWidth(bounds.getWidth());
clip.setHeight(bounds.getHeight());
}
});
stack.setClip(clip);
// layout everything.
VBox layout = new VBox();
layout.setPrefSize(250, 250);
layout.getChildren().setAll(stack, scaler);
VBox.setVgrow(stack, Priority.ALWAYS);
// show the stage.
stage.setScene(new Scene(layout));
stage.show();
}
}
I'm making a MenuBar, and I wan't the functionality to press a Menu like: "File" and then execute a action. Such like opening an other fxml, or an example where some output is written.
I want the functionality of a MenuItem (lie "About") in a Menu like "File".
package model;
import static java.lang.System.out;
import javafx.application.Application;
import javafx.beans.property.ReadOnlyDoubleProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.geometry.Side;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
/**
* Example of creating menus in JavaFX.
*
* #author Dustin
*/
public class JavaFxMenus extends Application
{
/**
* Build menu bar with included menus for this demonstration.
*
* #param menuWidthProperty Width to be bound to menu bar width.
* #return Menu Bar with menus included.
*/
private MenuBar buildMenuBarWithMenus(final ReadOnlyDoubleProperty menuWidthProperty)
{
final MenuBar menuBar = new MenuBar();
// Prepare left-most 'File' drop-down menu
final Menu fileMenu = new Menu("File");
menuBar.getMenus().add(fileMenu);
//menuBar.getOnMouseClicked().handle(this);
// Prepare 'Examples' drop-down menu
final Menu examplesMenu = new Menu("JavaFX 2.0 Examples");
examplesMenu.getItems().add(new MenuItem("Text Example"));
examplesMenu.getItems().add(new MenuItem("Objects Example"));
examplesMenu.getItems().add(new MenuItem("Animation Example"));
menuBar.getMenus().add(examplesMenu);
// Prepare 'Help' drop-down menu
final Menu helpMenu = new Menu("Help");
helpMenu.setOnAction(null);
final MenuItem searchMenuItem = new MenuItem("Search");
searchMenuItem.setDisable(true);
helpMenu.getItems().add(searchMenuItem);
final MenuItem onlineManualMenuItem = new MenuItem("Online Manual");
onlineManualMenuItem.setVisible(false);
helpMenu.getItems().add(onlineManualMenuItem);
helpMenu.getItems().add(new SeparatorMenuItem());
final MenuItem aboutMenuItem =
MenuItemBuilder.create()
.text("About")
.onAction(
new EventHandler<ActionEvent>()
{
#Override public void handle(ActionEvent e)
{
out.println("You clicked on About!");
}
})
.accelerator(
new KeyCodeCombination(
KeyCode.A, KeyCombination.CONTROL_DOWN))
.build();
helpMenu.getItems().add(aboutMenuItem);
menuBar.getMenus().add(helpMenu);
// bind width of menu bar to width of associated stage
menuBar.prefWidthProperty().bind(menuWidthProperty);
return menuBar;
}
/**
* Start of JavaFX application demonstrating menu support.
*
* #param stage Primary stage.
*/
#Override
public void start(final Stage stage)
{
stage.setTitle("Creating Menus with JavaFX 2.0");
final Group rootGroup = new Group();
final Scene scene = new Scene(rootGroup, 800, 400, Color.WHEAT);
final MenuBar menuBar = buildMenuBarWithMenus(stage.widthProperty());
rootGroup.getChildren().add(menuBar);
stage.setScene(scene);
stage.show();
}
/**
* Main executable function for running examples.
*
* #param arguments Command-line arguments: none expected.
*/
public static void main(final String[] arguments)
{
Application.launch(arguments);
}
}
AFAIK, A Menu, if has not any added submenu or Menuitems, does not fire events neither on click, on shown nor on hide. However the workaround is to set its graphic where this graphic node will handle mouse clicks for example,
Label menuLabel = new Label("File");
menuLabel.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
Stage myDialog = new Stage();
myDialog.initModality(Modality.WINDOW_MODAL);
Scene myDialogScene = new Scene(VBoxBuilder.create()
.children(new Text("Hello! it's My Dialog."))
.alignment(Pos.CENTER)
.padding(new Insets(10))
.build());
myDialog.setScene(myDialogScene);
myDialog.show();
}
});
Menu fileMenuButton = new Menu();
fileMenuButton.setGraphic(menuLabel);
menuBar.getMenus().add(fileMenuButton);
A drawback of this approach is that the label do not cover all spaces of the menu resulting clicking on edges of menu is not triggering the mouse event. See this by uncommenting menuLabel.setStyle line above. But this can be resolved by playing with CSS styles I think.
Code is partially taken from Create Dialog using Stage. You can also load an FXML file into the myDialog stage using the FXMLLoader. There are lots of examples about it on the net.
Recently i had the same problem, this is what i did
#FXML private Menu myMenu;
#Override
public void initialize(URL url, ResourceBundle rb) {
myMenu.setGraphic(
ButtonBuilder.create()
.text("btnText")
.onAction(new EventHandler<ActionEvent>(){
#Override public void handle(ActionEvent t) {
//TODO
} })
.build()
);
}
Combining with the answer from our friend #Dota2, i built a helper class to trigger the Menu's onAction(Menu menu) event even if it does not have any MenuItem inside. Here is the static helper method:
public static void onAction(Menu menu)
{
final MenuItem menuItem = new MenuItem();
menu.getItems().add(menuItem);
menu.addEventHandler(Menu.ON_SHOWN, event -> menu.hide());
menu.addEventHandler(Menu.ON_SHOWING, event -> menu.fire());
}
Then you call:
YourHelperClass.onAction(myMenu);
And ready! I hope this helps.
Recently I faced the same issue, this was my way out:
I had a menuItem in the menu, which was to behave as if the menuItem is clicked (in your case File menu). So what you can do is have a menuItem Dummy_menuItem
final Menu fileMenu = new Menu("File");
fileMenu.getItems().add(new MenuItem("Dummy_menuItem"));
menuBar.getMenus().add(fileMenu);
and then on click of File menu, fire the Dummy_menuItem menuItem or any functionality you wish to have. To identify which menu should have this property, I used numberOfMenuItems to get the number of menuItems in the menus in menubar
if (numberOfMenuItems == 1) {
menu.showingProperty().addListener(
(observableValue, oldValue, newValue) -> {
if (newValue) {
// the first menuItem is triggered
menu.getItems().get(0).fire();
}
}
);
}
the outcome is that the Dummy_menuItem is triggered without the context displaying the menuItem on click of File menu or any menu that has one menuItem. So it appears as if you clicked the File menu and were redirected to another page or whatever.
Hope this helps!!
I think you can't allow any action on the main Menu label.
However, you can create a stackpane, and fill it with text and a menu bar.