2 Replies Latest reply: Dec 20, 2012 3:42 AM by 979727 RSS

    Size of MenuItem

    979727
      I am using MenuButton a lot. To have a nice layout I often make the size of the button larger as needed just for nice layout purposes. What I can't get right yet is the size of the menuitems in a menubutton. It really looks bad if you have a large MenuButton and you open the menu that the contents is very small compared the button above.

      Anyway to change this?
        • 1. Re: Size of MenuItem
          jsmith
          This is not a good solution, but I could not come up with a good solution, so you can try this - at least it seems to work for me . . .
          import javafx.application.Application;
          import javafx.event.ActionEvent;
          import javafx.event.EventHandler;
          import javafx.scene.*;
          import javafx.scene.control.*;
          import javafx.scene.layout.*;
          import javafx.scene.paint.Color;
          import javafx.scene.shape.*;
          import javafx.scene.text.Text;
          import javafx.stage.Stage;
          
          /** Sizes the drop down menu for a menu button to at least same width as the menu button */
          public class MenuButtonSizing extends Application {
            private static final String FROBOZZ = "Frobozz";
            private static final String ZORK    = "Zork";
            
            public static void main(String[] args) { launch(args); }
            @Override public void start(Stage stage) {
              final MenuButton menuButton = new MenuButton("XYZZY is the Magic Word");
              final Label selection = new Label();
              
              final VBox layout = new VBox(30);
              layout.getChildren().setAll(selection, menuButton);
              layout.setStyle("-fx-background-color: cornsilk; -fx-padding: 50;");
              stage.setScene(new Scene(layout));
              stage.show();
              
              // for the sizing to work correctly, the SizingMenuItem must be created 
              // for the menu button after the menu button has been shown.
              SizingMenuItem frobozzItem = new SizingMenuItem(menuButton, FROBOZZ);
              frobozzItem.setOnAction(new EventHandler<ActionEvent>() {
                @Override public void handle(ActionEvent t) {
                  selection.setText(FROBOZZ);
                }
              });
              MenuItem zorkItem = new MenuItem(ZORK);
              zorkItem.setOnAction(new EventHandler<ActionEvent>() {
                @Override public void handle(ActionEvent t) {
                  selection.setText(ZORK);
                }
              });
              
              menuButton.getItems().setAll(
                      frobozzItem,
                      zorkItem
              );
            }
          
            class SizingMenuItem extends CustomMenuItem {
              static final double BUFFER_WIDTH = 14; // to account for the width of the padding around menu items.
              SizingMenuItem(final MenuButton menuButton, String string) {
                super();
                Text   text      = new Text(string);
                Double textWidth = text.getBoundsInParent().getWidth();
                Shape  padding = new Rectangle(
                        textWidth,
                        0,
                        menuButton.getWidth() - textWidth - BUFFER_WIDTH, 
                        2
                );
                padding.setFill(Color.TRANSPARENT);
                Label label = new Label(string, padding);
                label.setContentDisplay(ContentDisplay.RIGHT);
                label.setGraphicTextGap(0);
                setContent(label);
              }
            }  
          }
          • 2. Re: Size of MenuItem
            979727
            Perfect, many thanks. You pointed me in the right direction. I made some small changes however so that I do not need the EventHandler anymore. Just use a binding.
            import javafx.beans.binding.DoubleBinding;
            import javafx.scene.control.ContentDisplay;
            import javafx.scene.control.Label;
            import javafx.scene.control.MenuButton;
            import javafx.scene.control.MenuItem;
            
            public class SizingMenuItem extends MenuItem{
                
                static final double BUFFER_WIDTH = 14; // to account for the width of the padding around menu items.
                public SizingMenuItem(final MenuButton menuButton, String string) {
                  super();
                  Label label=new Label(string);
                  label.prefWidthProperty().bind(new DoubleBinding(){
                      
                      {
                          super.bind(menuButton.widthProperty());
                      }
            
                        @Override
                        protected double computeValue() {
                           return menuButton.widthProperty().get()-BUFFER_WIDTH;
                        }
                    });
                  label.setContentDisplay(ContentDisplay.RIGHT);
                  label.setGraphicTextGap(0);
                  setGraphic(label);
                 }
            }