B4J Question Detect multiple monitors

ThRuST

Well-Known Member
Licensed User
Longtime User
I want to use a for each loop to cycle through multiple monitors

Any clues how to do this?
 

ThRuST

Well-Known Member
Licensed User
Longtime User
This is my output from the log

(Screen) javafx.stage.Screen@db765fab bounds:Rectangle2D [minX = 0.0, minY=0.0, maxX=1920.0, maxY=1080.0, width=1920.0, height=1080.0] visualBounds:Rectangle2D [minX = 0.0, minY=0.0, maxX=1920.0, maxY=1040.0, width=1920.0, height=1040.0] dpi:92.0 renderScale:1.0
(Screen) javafx.stage.Screen@21438938 bounds:Rectangle2D [minX = -1920.0, minY=7.0, maxX=0.0, maxY=1087.0, width=1920.0, height=1080.0] visualBounds:Rectangle2D [minX = -1920.0, minY=7.0, maxX=0.0, maxY=1047.0, width=1920.0, height=1040.0] dpi:92.0 renderScale:1.0
 
Upvote 0

ThRuST

Well-Known Member
Licensed User
Longtime User
Cleaned up my example a bit by doing this

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

Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Private xui As XUI
    Private Button1 As B4XView
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.RootPane.LoadLayout("Layout1")
    MainForm.Show
End Sub

Sub Button1_Click
    
    For Each screen As Screen In fx.Screens
        Log(screen & CRLF & "----------------------------" & CRLF)
    Next
    
    'xui.MsgboxAsync("Hello World!", "B4X")
End Sub

Log
(Screen) javafx.stage.Screen@db765fab bounds:Rectangle2D [minX = 0.0, minY=0.0, maxX=1920.0, maxY=1080.0, width=1920.0, height=1080.0] visualBounds:Rectangle2D [minX = 0.0, minY=0.0, maxX=1920.0, maxY=1040.0, width=1920.0, height=1040.0] dpi:92.0 renderScale:1.0
----------------------------
(Screen) javafx.stage.Screen@21438938 bounds:Rectangle2D [minX = -1920.0, minY=7.0, maxX=0.0, maxY=1087.0, width=1920.0, height=1080.0] visualBounds:Rectangle2D [minX = -1920.0, minY=7.0, maxX=0.0, maxY=1047.0, width=1920.0, height=1040.0] dpi:92.0 renderScale:1.0
----------------------------
 
Upvote 0

Sandman

Expert
Licensed User
Longtime User
And how to detect the primary monitor?
You shouldn't assume there's a primary monitor. Just pick the first one in the list and then let the user move the app window as they like. Perhaps just store what monitor they moved the app window to so you can open it there next time they launch the app. (For reference, that's pretty much how VMware Horizon Client does it.)
 
Upvote 0

ThRuST

Well-Known Member
Licensed User
Longtime User
ok this might be overkill but it's part of my project, thereby my question. What I am trying to achieve is to detect if the user clicks within the screen to show the floating menu.
The borders should be ignored (to be able to rightclick on the tray icon on Win and Mac)

This example only targets the primary monitor. I want to make a check for all available monitors.
Any suggestions for this? oh wholy masters of B4X :)

B4X:
' If ignore borders are enabled in floating menu settings
If ToggleCheckbox4 = True Then

    ' Dynamically pause Floating menus on mouse X, Y pos
    StoreState = ToggleMenu
    
    For Each screen As Screen In fx.Screens

            If currentMouseX <=50 Or currentMouseY <=50 Or currentMouseX >=ScreenWidth - 50 Or currentMouseY >=ScreenHeight - 100 Then
                NativeHook_Static.Pause
            Else
        
                If StoreState = 1 Then
                    NativeHook_Static.ReStart
                End If
        
            End If
    
    Next

End If
 
Upvote 0

ThRuST

Well-Known Member
Licensed User
Longtime User
I probably should have included this in the example.. I use AWTRobot to check the cursor's position

B4X:
' Read mouse cursor position X & Y
        Dim m() As Int = AWTRobot0.RobotMouseCurrentLocation
        x = m(0)
        y = m(1)
        currentMouseX = m(0)
        currentMouseY = m(1)
 
Upvote 0

ThRuST

Well-Known Member
Licensed User
Longtime User
How to read individual properties from this screen object to find the second monitor from the log below? If there's more than two it becomes more relevant.
Should I use JavaObject for this?

(Screen) javafx.stage.Screen@db765fab bounds:Rectangle2D [minX = 0.0, minY=0.0, maxX=1920.0, maxY=1080.0, width=1920.0, height=1080.0] visualBounds:Rectangle2D [minX = 0.0, minY=0.0, maxX=1920.0, maxY=1040.0, width=1920.0, height=1040.0] dpi:92.0 renderScale:1.0
----------------------------
(Screen) javafx.stage.Screen@21438938 bounds:Rectangle2D [minX = -1920.0, minY=7.0, maxX=0.0, maxY=1087.0, width=1920.0, height=1080.0] visualBounds:Rectangle2D [minX = -1920.0, minY=7.0, maxX=0.0, maxY=1047.0, width=1920.0, height=1040.0] dpi:92.0 renderScale:1.0
----------------------------
 
Upvote 0

Sandman

Expert
Licensed User
Longtime User
Is it this part you want?
B4X:
minX = -1920.0, minY=7.0, maxX=0.0, maxY=1087.0, width=1920.0, height=1080.0
 
Upvote 0

ThRuST

Well-Known Member
Licensed User
Longtime User
@Sandman I wish there was a way to find out more information about each monitor, to define the rest from the primary one.
How would you do that?
 
Upvote 0

Star-Dust

Expert
Licensed User
Longtime User
B4X:
For Each S As Screen In fx.Screens
    Log(S.MinX & "," & S.MinY & "," & S.MaxX & "," & S.MaxY)
Next
 
Upvote 0

Star-Dust

Expert
Licensed User
Longtime User
If you want to know where each screen starts and ends use this code.

Then by reading the position of the mouse you can calculate which screen it is on

B4X:
Type MyDisplay(Left As Double, Top As Double, Width As Double, Height As Double)
Private Desktop(10) As MyDisplay
Private cnt As int = 0
    For Each o As JavaObject In fx.Screens
        Dim bounds As JavaObject = o.RunMethodjo("getBounds",Null)' required
        Dim minX As Double = bounds.RunMethod("getMinX",Null)'required
        Dim minY As Double = bounds.RunMethod("getMinY",Null)' required
        Dim width As Double = bounds.RunMethod("getWidth",Null)' required
        Dim height As Double = bounds.RunMethod("getHeight",Null)'required
        Log($"Screen is ${width} x ${height} pixels"$)' optional
        Log($"minimum X: ${minX}  minimum Y: ${minY}"$)' optional
        Desktop(cnt).Left = minX ' required
        Desktop(cnt).Top = minY ' required
        Desktop(cnt).Width = width ' required
        Desktop(cnt).Height = height ' required
        cnt = cnt + 1  ' required
    Next

see
 
Last edited:
Upvote 0
Top