B4J Question Question about context menus ...

MuuSer

Member
Licensed User
Longtime User
Hello!

How is possible to avoid text field native context menu (copy, paste, etc.) and invoke custom menu? So far I had them both in same time, but this is not good enough.

Or - another solution will be, if somehow is possible to invoke custom context menu programmatically, then there is no need to avoid native context menu of text field as I can invoke it with double-click.

Any ideas?

Thanks ahead.
 

Saverio

Member
Licensed User
Longtime User
Yes, I'm right,

dim mi(3) as MenuItem..... and everything will go fine
so this seems go well
B4X:
Sub Process_Globals
  Private fx As JFX
  Private MainForm As Form
  Dim cm As ContextMenu
  Dim mi(3) As MenuItem
  Dim jBeep As JavaObject
  jBeep.InitializeStatic("java.awt.Toolkit")
  jBeep = jBeep.RunMethod("getDefaultToolkit", Null)
  Dim lb1 As Label
  Dim jo As JavaObject
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
'  MainForm.Resizable = False
'  MainForm.SetFormStyle("UTILITY")
      lb1.Initialize("")
      MainForm.RootPane.AddNode(lb1, 100,300,300,100)
      MainForm.Show
   
    Dim smiClass As String = "javafx.scene.control.SeparatorMenuItem"
    Dim smi() As Object = Array(jo.InitializeNewInstance(smiClass,Null), _
                                jo.InitializeNewInstance(smiClass,Null))
   
    cm.Initialize("")
    mi(0).Initialize("MenuItem1","MenuItem")
    cm.MenuItems.Add(mi(0))
    cm.MenuItems.Add(smi(0))
    mi(1).Initialize("MenuItem2","MenuItem")
    cm.MenuItems.Add(mi(1))
    cm.MenuItems.Add(smi(1))
    mi(2).Initialize("MenuItem3","MenuItem")
    cm.MenuItems.Add(mi(2))
       
   
End Sub
Sub MainForm_MouseReleased(mData As MouseEvent)
    jo = cm
    If mData.SecondaryButtonPressed  Then
    jo.RunMethod("show", Array(MainForm.RootPane, _
      MainForm.WindowLeft + MainForm.WindowWidth - MainForm.Width - 8 + mData.x, _
      MainForm.WindowTop + MainForm.WindowHeight - MainForm.Height - 8 + mData.y))
    Else
    jo.RunMethod("hide",Null)
    End If
End Sub
Sub MenuItem_Action
    Dim Mitem As MenuItem = Sender
    lb1.Text = Mitem.Text & " was fired"
    Beep
End Sub
Sub Beep
  jBeep.RunMethod("beep", Null)
End Sub
 
Upvote 0

MuuSer

Member
Licensed User
Longtime User
B4X:
    cm.Initialize("")
    mi.Initialize("MenuItem1","MenuItem")
    cm.MenuItems.Add(mi)
    cm.MenuItems.Add(smi(0))
    Dim mi As MenuItem ' <=add this
    mi.Initialize("MenuItem2","MenuItem")
    cm.MenuItems.Add(mi)
    cm.MenuItems.Add(smi(1))
    Dim mi As MenuItem ' <= and this
    mi.Initialize("MenuItem3","MenuItem")
    cm.MenuItems.Add(mi)
 
Upvote 0

Saverio

Member
Licensed User
Longtime User
I know that.
The code of the above is just an example.
Indeed I'll use two List of MenuItem.
One for a static part of ContextMenu and another one for a dynamic part.
So I can adjust the last one time by time.

Thanks for your suggestion.

What I really need now is catch the onHiddenProperty event from the ContextMenu inherited from
javafx.stage.Window.

I've tried but failed.
Do you know something about that?
 
Upvote 0

Saverio

Member
Licensed User
Longtime User
Well well at the end I got it,
get also the onHidden event for ContextMenu.

If need one can use another event, see javafx reference.
this is just the starting point.

B4X:
Sub Process_Globals
  Private fx As JFX
  Private MainForm As Form
  Dim cm As ContextMenu
  Dim jBeep As JavaObject
  jBeep.InitializeStatic("java.awt.Toolkit")
  jBeep = jBeep.RunMethod("getDefaultToolkit", Null)
  Dim lb1 As Label
  Dim jo As JavaObject
 
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
'  MainForm.Resizable = False
'  MainForm.SetFormStyle("UTILITY")
      lb1.Initialize("")
      MainForm.RootPane.AddNode(lb1, 100,300,300,100)
      MainForm.Show
   
    'create 2 separator instances
    Dim smiClass As String = "javafx.scene.control.SeparatorMenuItem"
    Dim smi() As Object = Array(jo.InitializeNewInstance(smiClass,Null), _
                                jo.InitializeNewInstance(smiClass,Null))
   
    cm.Initialize("")
   
    Dim mi As MenuItem    '@MuuSer, Ok I admit it, your way is more clear, for now :-)
    mi.Initialize("MenuItem1","MenuItem")
    cm.MenuItems.Add(mi)
    cm.MenuItems.Add(smi(0))    'separator 1
   
    Dim mi As MenuItem
    mi.Initialize("MenuItem2","MenuItem")
    cm.MenuItems.Add(mi)
    cm.MenuItems.Add(smi(1))    'separator 2
   
    Dim mi As MenuItem
    mi.Initialize("MenuItem3","MenuItem")
    cm.MenuItems.Add(mi)

    'install an Handler for onHidden event
    'if needs can be changed with something else. see javafx ref.
    Dim cmEventHandler As Object = jo.CreateEventFromUI("javafx.event.EventHandler", _
                                                        "ctxMenuOnHidden",False)
    jo = cm
    jo.RunMethod("setOnHidden", Array(cmEventHandler))
   
End Sub

Sub ctxMenuOnHidden_Event(MethodName As String, Args() As Object)As Object
    Log("ContextMenu Hidden")
    Beep
    Return(True)
End Sub

Sub MainForm_MouseReleased(mData As MouseEvent)
    jo = cm
    If mData.SecondaryButtonPressed  Then
    jo.RunMethod("show", Array(MainForm.RootPane, _
      MainForm.WindowLeft + MainForm.WindowWidth - MainForm.Width - 8 + mData.x, _
      MainForm.WindowTop + MainForm.WindowHeight - MainForm.Height - 8 + mData.y))
    Else
    jo.RunMethod("hide",Null)
    End If
End Sub

Sub MenuItem_Action
    Dim Mitem As MenuItem = Sender
    lb1.Text = Mitem.Text & " was fired"
    Beep
End Sub

Sub Beep
  jBeep.RunMethod("beep", Null)
End Sub
 
Upvote 0

MuuSer

Member
Licensed User
Longtime User
Hello Saverio – good job!
If be honest, I had no idea and I wondered, why you need this onHidden event, but now my eyes are opened. So I modified your code little bit and now it obvious for everyone, I hope.
B4X:
Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Dim cm As ContextMenu
    Dim jBeep As JavaObject
    jBeep.InitializeStatic("java.awt.Toolkit")
    jBeep = jBeep.RunMethod("getDefaultToolkit", Null)
    Dim lb1 As Label
    Dim jo As JavaObject
    Dim AmountOfMenuItems As Int = 10
    Dim ContextMenuItemSelected As String
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
'  MainForm.Resizable = False
'  MainForm.SetFormStyle("UTILITY")
    lb1.Initialize("")
    MainForm.RootPane.AddNode(lb1, 100,300,300,100)
    MainForm.Show
 
    Dim smiClass As String = "javafx.scene.control.SeparatorMenuItem"
 
    cm.Initialize("")
 
    For I=1 To AmountOfMenuItems
        Dim mi As MenuItem
        mi.Initialize("MenuItem" & I,"MenuItem")
            cm.MenuItems.Add(mi)
        If I <> AmountOfMenuItems Then cm.MenuItems.Add(jo.InitializeNewInstance(smiClass,Null))
    Next

    'install an Handler for onHidden event
    'if needs can be changed with something else. see javafx ref.
    Dim cmEventHandler As Object = jo.CreateEventFromUI("javafx.event.EventHandler", _
                                                        "ctxMenuOnHidden",False)
    jo = cm
    jo.RunMethod("setOnHidden", Array(cmEventHandler))
 
End Sub

Sub ctxMenuOnHidden_Event(MethodName As String, Args() As Object)As Object
    If ContextMenuItemSelected <> "" Then
        Log("ContextMenu hidden after """ & ContextMenuItemSelected & """ selection.")
    Else
        Log("ContextMenu hidden without menuitem selection.")
    End If
    Beep
    Return(True)
End Sub

Sub MainForm_MouseReleased(mData As MouseEvent)
    ContextMenuItemSelected = ""
    jo = cm
    If mData.SecondaryButtonPressed  Then
        jo.RunMethod("show", Array(MainForm.RootPane, _
        MainForm.WindowLeft + MainForm.WindowWidth - MainForm.Width - 8 + mData.x, _
        MainForm.WindowTop + MainForm.WindowHeight - MainForm.Height - 8 + mData.y))
    Else
        jo.RunMethod("hide",Null)
    End If
End Sub

Sub MenuItem_Action
    Dim Mitem As MenuItem = Sender
    lb1.Text = Mitem.Text & " was fired"
    ContextMenuItemSelected = Mitem.Text
    Beep
End Sub

Sub Beep
    jBeep.RunMethod("beep", Null)
End Sub
 
Upvote 0

Saverio

Member
Licensed User
Longtime User
I think mine is more clear

btw the code of the above is just for tutorial matter.
My main porpouse was to see how to add a separator to a contex menu and
how to add a listener to an its event.

One could be do the same by using a ListView that should be more flexible and usefull
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…