B4J Code Snippet Get ContextMenus working on Nodes/Controls which do not support it

Discussion in 'B4J Code Snippets' started by moster67, Feb 14, 2019.

  1. moster67

    moster67 Expert Licensed User

    I though I would post this sample before I forget it and loose the code :)

    EDIT: Posted correct sample because last night I posted the wrong code.

    There are some Nodes/Controls which do not support setting a ContextMenu such as Pane, ImageView and some others.
    There are a lot of code/snippets here in the forum for ContextMenu but I couldn't find any code (unless I missed it) which could help me with nodes that do not support ContextMenu. There is a work-around posted where a button was used to get a ContextMenu over an ImageView but I couldn't get it to work that well.
    By googling, I noted that it can actually be done in a regular and proper way. Below code-sample is based on my findings.

    Code:
    #Region Project Attributes
        
    #MainFormWidth: 600
        
    #MainFormHeight: 600
    #End Region

    Sub Process_Globals
        
    Private fx As JFX
        
    Private MainForm As Form
        
    Private ContextMenu,ContextMenu1 As ContextMenu
        
    Private pane1 As Pane
        
    Private img As ImageView
       
    End Sub

    Sub AppStart (Form1 As Form, Args() As String)
        MainForm = Form1
        
    'MainForm.RootPane.LoadLayout("Layout1") 'Load the layout file.
       
        
    ContextMenu.Initialize("ContextMenu")
        ContextMenu1.Initialize(
    "ContextMenu1")
        pane1.Initialize(
    "pane1")
        img.Initialize(
    "img")
        
    Private bpm As Image
        bpm.Initialize(
    File.DirAssets,"Image1.jpg"'add your own image in the asset folder
        img.SetImage(bpm)
        MainForm.RootPane.AddNode(pane1, 
    200,100,100,100)
        MainForm.RootPane.AddNode(img,
    200,300,200,200)
        pane1.Style=
    "-fx-background-color: #FA7073"
       
        
    'add menuitems to the contextmenu
        Private MenuText() As String = Array As String("Open","Save as PNG","Save as JPEG")
        
    For i = 0 To MenuText.Length - 1
            
    Private TheMenuItem As MenuItem
            TheMenuItem.Initialize(MenuText(i),
    "cxm")
            
    ContextMenu.MenuItems.Add(TheMenuItem)
        
    Next
       
        
    Private MenuText1() As String = Array As String("A1","B2","C3")
        
    For i = 0 To MenuText1.Length - 1
            
    Private TheMenuItem As MenuItem
            TheMenuItem.Initialize(MenuText1(i),
    "cxm1")
            ContextMenu1.MenuItems.Add(TheMenuItem)
        
    Next
       
        
    'call the AddEventHandler sub for the nodes
        AddEventHandler(pane1,"pane1")
        AddEventHandler(img,
    "img")
        MainForm.Show
    End Sub


    Sub AddEventHandler(n As Node, EventName As String)
        
    'add an event handler and a ContextMenuEvent to the node which was passed
        Private joNode As JavaObject = n
        
    Private ev As Object = joNode.CreateEventFromUI("javafx.event.EventHandler",EventName,False)
        joNode.RunMethod(
    "setOnContextMenuRequested",Array(ev))
    End Sub

    Sub Pane1_MouseClicked(EventData As MouseEvent)
        
    'trap the mouseclicked event, get the necessary data and show the ContextMenu
        Private joCM As JavaObject = ContextMenu1
        
    Private joED As JavaObject = EventData
        
    Private ScreenX As Double = joED.RunMethod("getScreenX"Null)
        
    Private ScreenY As Double = joED.RunMethod("getScreenY"Null)
        joCM.RunMethod(
    "show",Array(pane1,ScreenX,ScreenY))
       
    End Sub

    Sub img_MouseClicked (EventData As MouseEvent)
        
    'trap the mouseclicked event, get the necessary data and show the ContextMenu
        Private joCM As JavaObject = ContextMenu
        
    Private joED As JavaObject = EventData
        
    Private ScreenX As Double = joED.RunMethod("getScreenX"Null)
        
    Private ScreenY As Double = joED.RunMethod("getScreenY"Null)
        joCM.RunMethod(
    "show",Array(img,ScreenX,ScreenY))
    End Sub

    Sub cxm_Action
        
    'get the sender, menuitem clicked and do something with it
        Private meit As MenuItem = Sender
        
    If meit.Text = "Open" Then
            
    Log("Open"'do something
        else if meit.Text = "Save as PNG" Then
            
    Log("Save as PNG"'do something
        else if meit.Text = "Save as JPEG" Then
            
    Log("Save as JPEG"'do something
        End If
    End Sub

    Sub cxm1_Action
        
    'get the sender, menuitem clicked and do something with it
        Private meit As MenuItem = Sender
        
    If meit.Text = "A1" Then
            
    Log("A1"'do something
        else if meit.Text = "B2" Then
            
    Log("B2"'do something
        else if meit.Text = "C3" Then
            
    Log("C3"'do something
        End If
    End Sub


    'Return true to allow the default exceptions handler to handle the uncaught exception.
    Sub Application_Error (Error As Exception, StackTrace As StringAs Boolean
        
    Return True
    End Sub
    upload_2019-2-14_23-53-22.png

    I guess you can improve the look and feel of the ContextMenu by using CSS but I didn't try that.

    Hope this turns useful for someone.
     
    Last edited: Feb 15, 2019
    ilan, matt humphreys, Erel and 3 others like this.
  2. moster67

    moster67 Expert Licensed User

    Updated first post with the correct sample because last night I posted the wrong code. Apparently I was too tired....
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice