Núcleo y utilidades · jdashboardUI 24 · B4J / JavaFX
ResponsiveUtils es una clase de apoyo para crear interfaces que se adapten al tamaño de un B4XView, al tamaño de un Form y a la pantalla donde se encuentra el usuario.
En B4J añade además utilidades para:
- calcular anchos y altos porcentuales;
- centrar un Form;
- dimensionar un Form como porcentaje de la pantalla;
- obtener dimensiones, coordenadas y escala de la pantalla;
- trabajar correctamente en configuraciones multi-monitor;
- adaptar Views durante
Base_Resize.
La clase no modifica automáticamente el layout. Proporciona cálculos y helpers para que el desarrollador los aplique donde corresponda.
Plataforma
El archivo fuente ResponsiveUtils.bas contiene ramas condicionales para B4J y B4A.
Sin embargo, el paquete analizado jdashboardUI 24 declara en su manifest.txt:
Supported Platforms=B4j
Por tanto, la documentación principal de esta versión corresponde a B4J. La API B4A existente en el fuente se documenta más adelante como referencia del código condicional.
Dependencias
ResponsiveUtils utiliza:
B4XView/ jXUI;JFXen B4J;JavaObjectpara consultar la escala real de salida de JavaFX;ScreenyFormde B4J.
No necesita AdditionalJar propio.
Initialize
La clase se vincula a un View base:
Private Responsive As ResponsiveUtils
Sub AppStart (Form1 As Form, Args() As String)
MainForm = Form1
MainForm.RootPane.LoadLayout("Main")
Responsive.Initialize(Root)
MainForm.Show
End Sub
Firma:
Responsive.Initialize(v As B4XView)
El View recibido se guarda internamente como mBase.
Normalmente se usa el Root, un Pane principal o cualquier View cuyo tamaño quieras tomar como referencia.
GetPercentX
Calcula un porcentaje del ancho actual del View vinculado.
Dim W As Double = Responsive.GetPercentX(80)
Equivale a:
mBase.Width * (Percent / 100)
Ejemplos:
Dim HalfWidth As Double = Responsive.GetPercentX(50)
Dim CardWidth As Double = Responsive.GetPercentX(30)
Dim Margin As Double = Responsive.GetPercentX(3)
No existe clamp interno: valores mayores de 100 o negativos también se calculan matemáticamente.
GetPercentY
Calcula un porcentaje de la altura actual del View vinculado.
Dim HeaderHeight As Double = Responsive.GetPercentY(12)
Dim ContentHeight As Double = Responsive.GetPercentY(80)
Equivale a:
mBase.Height * (Percent / 100)
GetBaseView
Devuelve exactamente el View usado en Initialize.
Dim Base As B4XView = Responsive.GetBaseView
Log(Base.Width)
Log(Base.Height)
Es útil cuando una clase recibe ResponsiveUtils y necesita recuperar el recurso visual original.
Uso con Base_Resize
ResponsiveUtils no escucha automáticamente los cambios de tamaño. En B4J, un patrón práctico es recalcular el layout dentro de Base_Resize.
Private Responsive As ResponsiveUtils
Private Sub B4XPage_Created (Root1 As B4XView)
Root = Root1
Root.LoadLayout("Dashboard")
Responsive.Initialize(Root)
End Sub
Private Sub B4XPage_Resize (Width As Int, Height As Int)
Dim Margin As Double = Responsive.GetPercentX(2)
Dim HeaderH As Double = Responsive.GetPercentY(12)
pnlHeader.SetLayoutAnimated(0, _
Margin, _
Margin, _
Responsive.GetPercentX(96), _
HeaderH)
pnlContent.SetLayoutAnimated(0, _
Margin, _
HeaderH + Margin * 2, _
Responsive.GetPercentX(96), _
Responsive.GetPercentY(82))
End Sub
Los porcentajes siempre se calculan usando el tamaño actual de mBase.
Layout de tarjetas proporcional
Ejemplo con tres tarjetas:
Private Sub B4XPage_Resize (Width As Int, Height As Int)
Dim Gap As Double = Responsive.GetPercentX(2)
Dim CardW As Double = Responsive.GetPercentX(30.66)
Dim CardH As Double = Responsive.GetPercentY(22)
Card1.SetLayoutAnimated(0, Gap, 20dip, CardW, CardH)
Card2.SetLayoutAnimated(0, Gap * 2 + CardW, 20dip, CardW, CardH)
Card3.SetLayoutAnimated(0, Gap * 3 + CardW * 2, 20dip, CardW, CardH)
End Sub
Este enfoque mantiene las proporciones cuando cambia el tamaño de la ventana.
Detección de pantalla activa
Los métodos de Form usan internamente GetScreenForForm, que es privado.
La selección de pantalla sigue este orden:
- intenta localizar la pantalla donde está actualmente el cursor del mouse;
- si no puede, intenta localizar la pantalla usando el centro horizontal del Form cuando tiene coordenadas y tamaño válidos;
- como fallback devuelve
fx.PrimaryScreen.
Esto permite que CenterForm y SetFormSizeByPercentage funcionen en sistemas con varios monitores.
Si el mouse está sobre otra pantalla al llamar estos métodos, esa pantalla puede ser elegida como destino aunque el Form todavía esté en otro monitor.
CenterForm
Centra el Form en la pantalla seleccionada.
Responsive.CenterForm(MainForm)
La implementación usa:
WindowLeft = MinX + (ScreenWidth / 2 - Form.Width / 2)
WindowTop = MinY + (ScreenHeight / 2 - Form.Height / 2)
Ejemplo:
MainForm.SetFormStyle("DECORATED")
MainForm.WindowWidth = 1100
MainForm.WindowHeight = 700
Responsive.CenterForm(MainForm)
MainForm.Show
GetScreenDimensions
Devuelve un Map con los datos de la pantalla seleccionada.
Dim Info As Map = Responsive.GetScreenDimensions(MainForm)
Log("Width: " & Info.Get("Width"))
Log("Height: " & Info.Get("Height"))
Log("Scale: " & Info.Get("Scale"))
Llaves devueltas:
| Llave | Tipo esperado | Descripción |
|---|---|---|
| Width | Double | Ancho de la pantalla |
| Height | Double | Alto de la pantalla |
| MinX | Double | Coordenada X mínima |
| MinY | Double | Coordenada Y mínima |
| MaxX | Double | Coordenada X máxima |
| MaxY | Double | Coordenada Y máxima |
| Scale | Double | Escala de salida JavaFX |
La escala se obtiene mediante:
Screen.getOutputScaleX()
Si esa llamada no está disponible o falla, Scale queda en 1.0.
Detectar HiDPI
Dim Info As Map = Responsive.GetScreenDimensions(MainForm)
Dim Scale As Double = Info.Get("Scale")
If Scale > 1 Then
Log("HiDPI / scaling detected: " & Scale)
End If
La clase devuelve la escala; no reescala automáticamente las fuentes ni los Views.
SetFormSizeByPercentage
Ajusta el tamaño del Form usando porcentajes de la pantalla y después lo centra.
Responsive.SetFormSizeByPercentage(MainForm, 80, 70)
En este ejemplo:
- ancho = 80% de la pantalla;
- alto = 70% de la pantalla;
- el Form queda centrado.
Ejemplo de inicio:
Sub AppStart (Form1 As Form, Args() As String)
MainForm = Form1
MainForm.RootPane.LoadLayout("Main")
Responsive.Initialize(MainForm.RootPane)
Responsive.SetFormSizeByPercentage(MainForm, 85, 82)
MainForm.Show
End Sub
Los comentarios del fuente indican que WidthPercent y HeightPercent deben estar entre 0 y 100.
La implementación actual no aplica clamp, así que es responsabilidad del desarrollador respetar ese rango.
GetFormRelativeWidth
Devuelve un porcentaje del ancho actual del Form.
Dim SidebarW As Double = Responsive.GetFormRelativeWidth(MainForm, 20)
Dim ContentW As Double = Responsive.GetFormRelativeWidth(MainForm, 80)
Implementación:
f.Width * (Percent / 100)
GetFormRelativeHeight
Devuelve un porcentaje de la altura actual del Form.
Dim ToolbarH As Double = Responsive.GetFormRelativeHeight(MainForm, 8)
Implementación:
f.Height * (Percent / 100)
Ejemplo completo B4J
Este ejemplo combina tamaño inicial relativo a la pantalla y layout proporcional al Root.
Sub Process_Globals
Private fx As JFX
Private MainForm As Form
Private xui As XUI
Private Responsive As ResponsiveUtils
Private pnlSidebar As B4XView
Private pnlContent As B4XView
Private pnlHeader As B4XView
End Sub
Sub AppStart (Form1 As Form, Args() As String)
MainForm = Form1
MainForm.RootPane.LoadLayout("Main")
Responsive.Initialize(MainForm.RootPane)
'85% del ancho y 80% del alto de la pantalla activa.
Responsive.SetFormSizeByPercentage(MainForm, 85, 80)
MainForm.Show
End Sub
Private Sub MainForm_Resize (Width As Double, Height As Double)
Dim Margin As Double = Responsive.GetPercentX(2)
Dim HeaderH As Double = Responsive.GetPercentY(10)
Dim SidebarW As Double = Responsive.GetPercentX(22)
pnlHeader.SetLayoutAnimated(0, _
Margin, _
Margin, _
Responsive.GetPercentX(96), _
HeaderH)
pnlSidebar.SetLayoutAnimated(0, _
Margin, _
HeaderH + Margin * 2, _
SidebarW, _
Responsive.GetPercentY(84))
pnlContent.SetLayoutAnimated(0, _
SidebarW + Margin * 2, _
HeaderH + Margin * 2, _
Responsive.GetPercentX(96) - SidebarW - Margin, _
Responsive.GetPercentY(84))
End Sub
Multi-monitor
Para obtener información de la pantalla que ResponsiveUtils considera activa:
Dim ScreenInfo As Map = Responsive.GetScreenDimensions(MainForm)
Log("Monitor origin: " & _
ScreenInfo.Get("MinX") & ", " & _
ScreenInfo.Get("MinY"))
Log("Monitor size: " & _
ScreenInfo.Get("Width") & " x " & _
ScreenInfo.Get("Height"))
En monitores situados a la izquierda o encima del monitor principal, MinX o MinY pueden ser negativos. Esto es normal.
Rama B4A presente en el fuente
Aunque el paquete actual de jdashboardUI 24 está marcado como B4J, ResponsiveUtils.bas contiene código B4A condicional.
En B4A se encuentran:
GetScreenDimensions As Map
GetFormRelativeWidth(Percent As Double) As Double
GetFormRelativeHeight(Percent As Double) As Double
GetScreenDimensions — B4A
Usa GetDeviceLayoutValues y devuelve las mismas llaves:
Width
Height
MinX
MinY
MaxX
MaxY
Scale
GetFormRelativeWidth — B4A
100%x * (Percent / 100)
GetFormRelativeHeight — B4A
100%y * (Percent / 100)
Estos métodos se documentan porque existen en el fuente, pero no convierten el paquete actual en una librería B4A: el manifest de la versión analizada declara únicamente B4J.
API pública completa
API común
| Método | Retorno | Descripción |
|---|---|---|
| Initialize(v As B4XView) | - | Vincula el View base |
| GetPercentX(Percent As Double) | Double | Porcentaje del ancho de mBase |
| GetPercentY(Percent As Double) | Double | Porcentaje del alto de mBase |
| GetBaseView | B4XView | Devuelve mBase |
API B4J
| Método | Retorno | Descripción |
|---|---|---|
| CenterForm(f As Form) | - | Centra el Form en la pantalla seleccionada |
| GetScreenDimensions(f As Form) | Map | Dimensiones, coordenadas y escala |
| SetFormSizeByPercentage(f, WidthPercent, HeightPercent) | - | Redimensiona y centra el Form |
| GetFormRelativeWidth(f, Percent) | Double | Porcentaje del ancho del Form |
| GetFormRelativeHeight(f, Percent) | Double | Porcentaje del alto del Form |
API B4A existente en el fuente
| Método | Retorno | Descripción |
|---|---|---|
| GetScreenDimensions | Map | Dimensiones y escala del dispositivo |
| GetFormRelativeWidth(Percent) | Double | Porcentaje de 100%x |
| GetFormRelativeHeight(Percent) | Double | Porcentaje de 100%y |
Designer, eventos y AddToParent
ResponsiveUtils es una clase auxiliar:
- no tiene Designer Properties;
- no expone eventos;
- no implementa
AddToParent; - no crea Views;
- no cambia automáticamente el layout;
- requiere
Initializecon unB4XView.
Buenas prácticas
- Inicializa la clase con el contenedor que realmente representa el área responsive.
- Usa
GetPercentXyGetPercentYdentro de eventos Resize cuando quieras adaptación dinámica. - Usa
SetFormSizeByPercentagepara el tamaño inicial del Form, no en cada frame de resize. - Mantén
WidthPercentyHeightPercententre 0 y 100. - Recuerda que la detección B4J da prioridad a la pantalla donde está el cursor.
- No asumas que
MinXyMinYson siempre 0 en configuraciones multi-monitor. - Usa
Scalecomo información; ResponsiveUtils no cambia fuentes ni escala de UI automáticamente. - Si necesitas considerar barra de tareas o dock, comprueba si las dimensiones completas de
Screenson apropiadas para tu caso.