B4J Tutorial Designer Menu Items

Discussion in 'B4J Tutorials' started by Erel, Jul 26, 2015.

Similar threads

B4J Question ? Menu bar configuration
B4J Question Menuitem without childrens: where's the event ?
B4J Tutorial TreeTableView
Share My Creation Menu Designer
B4J Question Menu not actioning action.
  1. Erel

    Erel Administrator Staff Member Licensed User

    Menus in the internal designer are declared as JSON strings.

    If you have never worked with the JSON format then it is a good time to learn this format. It is simple and very popular. Short tutorial: http://www.vogella.com/tutorials/JSON/article.html

    In our case the JSON string describes a list of menu items. Each menu item can hold other menu items.
    Each item can be described as a simple string or as a map.
    Simple context menu:
    Code:
    ["Context Item #1""Context Item #2""Context Item #3"]
    The result is:

    [​IMG]


    To access all the attributes of each item you need to use the map format.
    The following fields are available (note that the field names are case sensitive):

    Text - The item's text. This is the only required field. Underscore sets the mnemonic character.
    EventName - Sets the sub that will handle the events. If not set then the EventName will be the same as the control's event name property.
    Tag - An arbitrary string that will be set as the item's tag.
    Enabled - Sets whether the menu item is enabled. This is a boolean value (without quotes).
    Children - Holds a list of child menu items.
    Selected - Sets whether the menu item is checked or not.
    Image - Image file name.

    Example:
    Code:
    [
       {Text: 
    "_File", Children:
         [
    "_New""_Save",
         {Text: 
    "_Export", Children: ["Zip File""Tar File"]},
         "-",
         "_Close"]
       },
       {Text: "_Edit", Children:[] },
       {Text: "_Help", Children:
         [
           {Text: "Disabled Item", Enabled: False},
           {Text: "Item With Unique Event Name",
             EventName: "mnu1234",
             Image: "EffectNone.png" },
      {Text: "Item With Tag", Tag: "MyTag"}
         ]
       }
    ]
    Result:

    [​IMG]


    Context Menus


    [​IMG]

    MenuBar

    [​IMG]

    Note that the top menus of the MenuBar must have a Children attribute.

    Use a simple string item with the value of "-" to create a separator.

    Events

    The Action event will be raised when a menu item is clicked. By default the event name (sub prefix) will be the same as the parent control event name.
    You can get the menu item with code similar to:
    Code:
    Sub MenuBar1_Action
       
    Dim mi As MenuItem = Sender

    End Sub
    You can get the Tag or Text from the menu item to decide on the required action.

    Shortcuts (accelerators)

    [​IMG]

    You can add shortcut keys to menu items. This is done with the Shortcut key. The value is a map with Key and optionally one or more modifiers.

    For example to assign F1 as the shortcut:
    Code:
    {Text: "Item1", Shortcut: {Key: "F1"}}
    Ctrl + S:
    Code:
    {Text: "Item1", Shortcut: {Key: "S", Modifier: "CONTROL"}}
    Ctrl + Alt + S:
    Code:
    {Text: "Item1", Shortcut: {Key: "S", Modifier: ["CONTROL""ALT"]}}
    The possible modifiers values: ALT, CONTROL, SHIFT and SHORTCUT (Mac button).
     
    Last edited: Jul 29, 2015
    Magma, Toley, billzhan and 2 others like this.
  2. tdocs2

    tdocs2 Well-Known Member Licensed User

    Thank you, Erel.

    I must sound like a newbie (and in B4J, I am), but I cannot figure out how to capture the event when "_New" is clicked.

    Also, when a map is specified:

    Code:
    {Text: "Item With Unique Event Name",
             EventName: 
    "mnu1234",
             
    Image"EffectNone.png" },
    do I set up a Sub mnu1234?

    Sandy

    WISH: A separate Menu Designer for B4J - that matches the simplicity of the Internal Designer. Generates events for all menu items, specifies structure, etc. (All my wishes are BIG WISHES:))

    Thank you, Erel - if you truly achieve a B4J, B4A, and B4i unified and transparent environment (or close)... Not a WISH more like a DREAM..
     
  3. Erel

    Erel Administrator Staff Member Licensed User

    In the example above (first post) the EventName is not set. This means that the MenuBar event name will be used. So it should be:
    Code:
    Sub MenuBar1_Action
    This will handle the events of all the menu items except the ones that explicitly set the event name.

    Code:
    Sub mnu1234_Action
     
    tdocs2 likes this.
  4. tdocs2

    tdocs2 Well-Known Member Licensed User

    Thank you, Erel.

    I am still having problems (newbie, newbie):

    Code:
    ub MenuBar1_Action
         
    Log("Save")
         
    Dim mi As MenuItem = Sender
        
        
    End Sub
    How do I capture _Save?

    Sandy
     
  5. Erel

    Erel Administrator Staff Member Licensed User

    You have several options.
    You can set a different EventName value to the save item or handle it with:
    Code:
    Sub MenuBar1_Action
     
    Dim mi As MenuItem = Sender
     
    If mi.Text = "_Save" Then ...
    End Sub
    Another option is to use the Tag property instead of the Text property.
     
    tdocs2 likes this.
  6. tdocs2

    tdocs2 Well-Known Member Licensed User

    Thank you, Erel.
     
  7. derez

    derez Expert Licensed User

    miker2069, AlbertDE and tdocs2 like this.
  8. tdocs2

    tdocs2 Well-Known Member Licensed User

    Thank you, Derez.

    I will give it a try....

    Best regards.

    Sandy
     
  9. derez

    derez Expert Licensed User

    How can I change the status of Enabled/Disabled item by code in the application ?
    Example: I have two items, Save and Save As. Save should be disabled until a filename is selected using Save As.
     
  10. Erel

    Erel Administrator Staff Member Licensed User

    You can use this code to build a map based on the menu items tag:
    Code:
    Private Sub CollectMenuItems(Menus As Map, Items As List)
       
    For Each mi As MenuItem In Items
         
    If mi.Tag <> Null And mi.Tag <> "" Then Menus.Put(mi.Tag, mi)
         
    If mi Is Menu Then
           
    Dim mn As Menu = mi
           CollectMenuItems(Menus, mn.MenuItems)
         
    End If
       
    Next
    End Sub
    Now you will have simple access to all menu items with tags.
    Code:
    Dim menus As  Map 'better to make it a global variable
    menus.Initialize
    CollectMenuItems(menus, MenuBar1.Menus)
    Dim mi As MenuItem = menus.Get("MyTag")
    mi.Enabled = 
    False
    Edit: added the missing call to CollectMenuItems.
     
    Last edited: Aug 5, 2015
    tdocs2 likes this.
  11. derez

    derez Expert Licensed User

    Code:
    Private Sub CollectMenuItems(Menus As Map, Items As List)
    How do I create the items list of menuitems ?
     
  12. Erel

    Erel Administrator Staff Member Licensed User

    Code:
    Dim menus As Map
    menus.Initialize
    CollectMenuItems(menus, MenuBar1.Menus)
     
    kazem forghani likes this.
  13. derez

    derez Expert Licensed User

    Thank you
     
  14. Hanstel

    Hanstel Member Licensed User

    im completely new to b4j, is "Designer Menu Item" working for web apps too? how about the context menu invoke by right-click?
     
  15. GMan

    GMan Well-Known Member Licensed User

    Hoi Erel, i got an error with the example code:

    org.json.JSONException: Expected literal value at character 356 of [

    The rest is the pasted code from Post one
     
  16. GMan

    GMan Well-Known Member Licensed User

    Just deleted the old menubar and inserted a new one - works again.
    So maybe the code above has an issue ?
     
  17. Erel

    Erel Administrator Staff Member Licensed User

    I tested it and it works. You do need to delete the image field or change it to an existing image.
     
    GMan likes this.
  18. Saverio

    Saverio Member Licensed User

    Assign just "F1" key, without any Modifier, will not fire any event, unless handle by code the KeyEvent.
    Even setting all the modifiers to "ignore"(ref. KeyCombination: getName) that will set all the modifier state as "ANY".
    At least on my pc, win7 - jdk1.8.0_131, with Italian keyboard layout.
    As I read on the net, it is an intetional limitation by javafx team.
    So I say, why show "F1" as shortcut, in the menuitem, and then do not fire any event?
    Can you confirm that?
    Thanks
     
  19. Erel

    Erel Administrator Staff Member Licensed User

    It works fine here. Just added a MenuBar with the designer and added this code (with the default menu template):
    Code:
    Sub MenuBar1_Action
       
    Log(Sender)
    End Sub
     
  20. Saverio

    Saverio Member Licensed User

    Ok, I leave out some detail...sorry :)

    Maked just fresh app with a MenuBar and a TextArea.
    When the TextArea has the focus, here, isn't work.
    A Shortcut should behave system wide or, at least, application wide.
    Note: I'm not saying that it is a B4J fault.
     

    Attached Files:

Loading...