B4J Question Mouse Event (getX and getY) in trasparent area

micro

Well-Known Member
Licensed User
Longtime User
Hi to all, another question.
How can I get the X and Y position of the Mouse event even in transparent areas?
I have a fullscreen program but when I hover over a transparent zone the X and Y coordinates do not update.
Thanks
 

micro

Well-Known Member
Licensed User
Longtime User
1655091721961.png
 
Upvote 0

micro

Well-Known Member
Licensed User
Longtime User
No. It should be MainForm_MouseMoved (non-B4XPages project).
Yes, yes
The Sub is
MainForm_MouseMoved
I just wrote wrong here.

If you do a test you will realize that in that transparent area the event does not happen
 
Upvote 0

kimstudio

Active Member
Licensed User
Longtime User
Interesting finding. I can't believe it so I tried and yes you are right. If the pane is transparent the move event will also not fire on that pane.
 
Upvote 0

micro

Well-Known Member
Licensed User
Longtime User
Add a Pane to that area.
Troppo semplice LucaMs, il pannello non deve essere solido altrimenti non ci sono problemi
A me serve quella zona trasparente perchè all'interno mostro un programma esterno.

Too simple LucaMs, the panel must not be solid otherwise there is no problem
I need that transparent area because inside I show an external program.


This is as it should be, so pnTransparent does not is needed
B4X:
Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.SetFormStyle("TRANSPARENT")
    MainForm.RootPane.LoadLayout("Layout1")
    MainForm.BackColor = fx.Colors.Transparent
    pnTransparent.Style = "-fx-background-color:transparent;"
    MainForm.Show
End Sub

thanks anyway for your interest.
 
Upvote 0

kimstudio

Active Member
Licensed User
Longtime User
Searched the issue and found out that it seems this is a Windows problem, not related to JavaFx. An ugly solution is to put a pane on that transparent area and set its alpha to 0.1. It's not totally transparent but better than nothing. I tried and it works and 0.1 alpha is almost transparent - hardly to distinguish.
 
Upvote 0

micro

Well-Known Member
Licensed User
Longtime User
Searched the issue and found out that it seems this is a Windows problem, not related to JavaFx. An ugly solution is to put a pane on that transparent area and set its alpha to 0.1. It's not totally transparent but better than nothing. I tried and it works and 0.1 alpha is almost transparent - hardly to distinguish.
It is right what you say but with transparency not at the maximum I can no longer interact with what is in the transparent area
Thanks
 
Upvote 0

kimstudio

Active Member
Licensed User
Longtime User
Not tried: make your window always on top and for the transparent area the mouse event already can penetrate and interact with layer down windows, then the mouse position can be obtained from whole screen system mouse position as your windows is full screen.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Out of curiosity, I thought I'd try a solution using Roycefers jNativeHook library. There are obvious potential issues using this kind of library, mainly it is important to make sure that you stop the native hook when the app is closed. Due to it's nature, it is not simple to work with, but it can be very effective and I have an app that relies on it which I use daily and have done for the last 3 or 4 years with no issues.

Please read carefully Roycefer's comments in the library post.

I have tested this on java 8 and 11, and have added the code to capture mouse press which you may want and requires the Threading library and therefore may not run properly in debug mode unless you compile it to a library. If you don't need it I suggest that you remove it.

It's not going to be perfect as it stands but should give you a start. I hope this helps.
 

Attachments

  • MouseOver_transparent_form.zip
    3.6 KB · Views: 125
Last edited:
Upvote 0

micro

Well-Known Member
Licensed User
Longtime User
Out of curiosity, I thought I'd try a solution using Roycefers jNativeHook library. There are obvious potential issues using this kind of library, mainly it is important to make sure that you stop the native hook when the app is closed. Due to it's nature, it is not simple to work with, but it can be very effective and I have an app that relies on it which I use daily and have done for the last 3 or 4 years with no issues.

Please read carefully Roycefer's comments in the library post.

I have tested this on java 8 and 11, and have added the code to capture mouse press which you may want and requires the Threading library and therefore may not run properly in debug mode unless you compile it to a library. If you don't need it I suggest that you remove it.

It's not going to be perfect as it stands but should give you a start. I hope this helps.
Perfect stevel05
Thank you very much
 
Upvote 0

kimstudio

Active Member
Licensed User
Longtime User
Thanks stevel05 I learned something. I tried your solution it works smoothly and also capture mouse action event.

I found if you don't need mouse action event then put a timer in that fires at high frequency and call following java code in tick you get screen mouse position easily:

Java:
#If JAVA
import java.awt.MouseInfo;
public static double ScreenMousePos() {
    return MouseInfo.getPointerInfo().getLocation().getX();
}
#End If
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
@kimstudio Indeed:

B4X:
'Process Globals
Private AMP As AwtMousePointer

.
.
'Appstart
AMP.Initialize(Me, MainForm)

.
.

Private Sub AWTMousePointer_MouseMoved(X As Int, Y As Int)
    Log(X  & ", " & Y)
End Sub


Class AWTMousePointer :

B4X:
#Event: MouseMoved(X as Int, Y as Int)
Sub Class_Globals
    Private fx As JFX
    Private MPTimer As Timer
    Private MouseInfo As JavaObject
    Private MouseMoved As Boolean
    Private mCallBack As Object
    Type MousepointerType(X As Int, Y As Int)
    Private MPT As MousepointerType
    Private TargetForm As Form
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize(Callback As Object, F As Form)
    mCallBack = Callback
    TargetForm = F
    MPTimer.Initialize("MPTimer",100)
    MouseInfo.InitializeStatic("java.awt.MouseInfo")
    MouseMoved = SubExists(mCallBack,"AWTMousePointer_MouseMoved")
    MPT.Initialize
    MPTimer.Enabled = True
End Sub

Private Sub MPTimer_Tick
    Dim Location As JavaObject = MouseInfo.RunMethodJO("getPointerInfo",Null).RunMethodJO("getLocation",Null)
    Dim NewMPT As MousepointerType
    NewMPT.Initialize
    NewMPT.X = Location.RunMethod("getX",Null)
    NewMPT.Y = Location.RunMethod("getY",Null)
 
    If NewMPT.X = MPT.X And NewMPT.Y = MPT.Y Then Return
 
    MPT = NewMPT
 
    If MouseMoved And OverWindow(MPT) Then
        CallSub3(mCallBack,"AWTMousePointer_MouseMoved",(MPT.x - TargetForm.WindowLeft).As(Int), (MPT.Y - TargetForm.WindowTop).As(Int))
    End If
 
End Sub

Private Sub OverWindow(TMPT As MousepointerType) As Boolean
 
    If TMPT.X >= TargetForm.WindowLeft And _
    TMPT.X <= TargetForm.WindowLeft + TargetForm.WindowWidth And _
    TMPT.Y >= TargetForm.WindowTop And _
    TMPT.Y <= TargetForm.WindowTop + TargetForm.WindowHeight Then
        Return True
    Else
        Return False
    End If
 
End Sub
 

Attachments

  • MousePointer.zip
    3 KB · Views: 132
Upvote 0

kimstudio

Active Member
Licensed User
Longtime User
Thanks stevel, nice example of how to use javaobject and encapsulate it in a class!

I think this topic relates to potential screen capture application, which is kind of advanced "hello world" for learning a new language. It should be in this forum somewhere but maybe it is not easy to implement with this transparent issue - use mouse to select a rectangle of screen and capture it into a image.
 
Upvote 0
Top