Technical Support
🟢 Online now
Hello 👋

How can we help you today?
Contact on WhatsApp
B4X Store
jdashboardUI / Núcleo y utilidades / jdashboard_WindowsStyle
Núcleo y utilidades

jdashboard_WindowsStyle

Base de ventana moderna: barra superior, botones del sistema, RootPane, resize, sombras, animaciones, menús laterales y multi-monitor

Buscar en toda jdashboardUI
Fuente
jdashboardUI.b4xlib · Solo API pública
Idioma de la tienda: es
Referencias visuales — jdashboard_WindowsStyle
Estas maquetas muestran la función real de WindowsStyle como base de la ventana moderna. Los diseños interiores son ejemplos de aplicaciones construidas sobre el mismo shell; no son temas incorporados.
REFERENCE
Anatomía de jdashboard WindowsStyle con Title, BarPanel, botones superiores y RootPane
Anatomía del shell: icono, título, BarPanel, hbWindowTopButtons, zonas de resize y RootPane/pbase. El menú lateral y el contenido son responsabilidad de la aplicación.
Diferentes diseños de aplicaciones construidos sobre el mismo WindowsStyle
Licensr Pro, LibX Template Studio, una aplicación de seguridad y un dashboard claro ilustran la idea principal: WindowsStyle no impone una apariencia; proporciona la base moderna sobre la que cada aplicación define su identidad.
Estados, MenuType, resize, BarPanel, RootPane y comportamiento multi-monitor de WindowsStyle
Comportamiento de layout: ventana normal/maximizada, zonas de resize, reservas MenuType, BarPanel, RootPane y SetSizeByPercentage al mover la ventana entre monitores.

Qué es

jdashboard_WindowsStyle es la base de ventana moderna de jdashboardUI para B4J. Convierte un Form normal en una ventana sin marco nativo y crea la estructura sobre la que después pueden montarse Ribbon, menús laterales, dashboards, tablas, editores, visores PDF y cualquier otro contenido.

No es un tema cerrado ni obliga a que todas las aplicaciones se vean iguales. Precisamente por eso aplicaciones tan distintas como Licensr Pro, LibX Template Studio, B4X Antivirus Pro o DataFlow pueden usar la misma base de ventana y tener diseños completamente diferentes.

WindowsStyle administra principalmente:

  • barra superior personalizada;
  • icono y título;
  • botones de minimizar, maximizar / restaurar, cerrar y pantalla completa;
  • botones propios con iconos o imágenes;
  • área central para controles personalizados;
  • RootPane para el contenido de la aplicación;
  • arrastre de la ventana;
  • redimensionamiento;
  • bordes y esquinas redondeadas;
  • sombras;
  • Always On Top;
  • animación al maximizar / restaurar;
  • límites mínimos y máximos;
  • tamaño por porcentaje de pantalla;
  • adaptación multi-monitor;
  • reserva de espacio para menús laterales mediante MenuType.

La implementación real utiliza un Form transparente, carga internamente jCustomWindow.fxml y agrega fluent-light.css.


Por qué es una pieza central de jdashboardUI

WindowsStyle no dibuja por sí solo un dashboard completo. Su trabajo es proporcionar el shell moderno de la aplicación.

Una forma sencilla de entenderlo es:

jdashboard_WindowsStyle
        ↓
ventana + barra superior + acciones + RootPane
        ↓
tu diseño
        ↓
Ribbon / menú lateral / tablas / gráficos / editores / formularios

Esto permite separar dos responsabilidades:

  1. WindowsStyle controla la ventana.
  2. El desarrollador controla el contenido y la identidad visual.

Por eso una misma clase puede servir para una aplicación oscura de licencias, un editor con degradados, una aplicación de seguridad o un dashboard claro.


Anatomía real de la ventana

La estructura interna principal es:

Form transparente
├── apWindowTop
│   ├── icono
│   ├── Title
│   ├── BarPanel
│   └── hbWindowTopButtons
├── apWindowLeft
├── apWindowRight
├── apWindowBottom
└── RootPane / pbase
    └── contenido de tu aplicación

El RootPane público no es el RootPane nativo del Form. Devuelve pbase, que es el área preparada para colocar el contenido real.

Ejemplo:

ui.RootPane.LoadLayout("Main")

Cuando usas Ribbon, una tabla, un editor o un visor, normalmente debes cargarlo dentro de ui.RootPane.


Inicialización

Firma real:

Initialize( _
    moduleParent As Object, _
    parentForm As Form, _
    eventName As String, _
    color As Paint)

Ejemplo básico:

Sub Process_Globals
    Private fx As JFX
    Private xui As XUI
    Private MainForm As Form
    Private ui As jdashboard_WindowsStyle
End Sub

Sub AppStart(Form1 As Form, Args() As String)
    MainForm = Form1

    ui.Initialize( _
        Me, _
        MainForm, _
        "ui", _
        fx.Colors.RGB(30, 30, 46))

    ui.Title.Text = "My Application"
    ui.Title.TextColor = fx.Colors.White

    ui.AddIconButton( _
        "close", _
        Chr(0xE14C), _
        fx.Colors.White, _
        fx.CreateMaterialIcons(22), _
        ui.ACTION_EXIT, _
        "Close")

    ui.AddIconButton( _
        "maximize", _
        Chr(0xE3E0), _
        fx.Colors.White, _
        fx.CreateMaterialIcons(22), _
        ui.ACTION_MAXIMIZE, _
        "Maximize")

    ui.AddIconButton( _
        "minimize", _
        Chr(0xE15B), _
        fx.Colors.White, _
        fx.CreateMaterialIcons(22), _
        ui.ACTION_MINIMIZE, _
        "Minimize")

    ui.RootPane.LoadLayout("Main")
    MainForm.Show
End Sub

Durante Initialize, la clase:

  • pone el Form en estilo TRANSPARENT;
  • hace transparente la escena JavaFX;
  • elimina el borde nativo;
  • aplica radio al RootPane exterior;
  • carga jCustomWindow.fxml;
  • prepara pbase;
  • centra la ventana;
  • configura el resize;
  • inicia el Timer de animación;
  • registra listeners X/Y del Stage para multi-monitor;
  • crea BarPanel;
  • aplica Always On Top con su valor actual;
  • agrega fluent-light.css.

Ejemplo real de uso

Un patrón usado en aplicaciones construidas con jdashboardUI es:

ui.Initialize(Me, MainForm, "ui", fx.Colors.RGB(30, 30, 46))

ui.SetSizeByPercentage(75, 86)

ui.Title.Text = "Ribbon UI Studio Pro"
ui.Title.TextColor = fx.Colors.White
ui.Title.Font = xui.CreateDefaultBoldFont(12)

ui.SetIcon(fx.LoadImage(File.DirAssets, "app.png"))
ui.titlestyle(xui.Color_RGB(67, 67, 77))

ui.AnimationsActivated = False
ui.AlwaysOnTop = False

ui.AddIconButton("close", Chr(0xE14C), fx.Colors.White, _
    fx.CreateMaterialIcons(22), ui.ACTION_EXIT, "Cerrar")

ui.AddIconButton("maximize", Chr(0xE3E0), fx.Colors.White, _
    fx.CreateMaterialIcons(22), ui.ACTION_MAXIMIZE, "Maximizar")

ui.AddIconButton("minimize", Chr(0xE15B), fx.Colors.White, _
    fx.CreateMaterialIcons(22), ui.ACTION_MINIMIZE, "Minimizar")

MainForm.Show
ui.RootPane.LoadLayout("Layout1")

La idea importante es que WindowsStyle prepara la ventana primero y el contenido se carga después dentro de RootPane.


Title

Title devuelve el Label real de la barra superior.

ui.Title.Text = "Licensr Pro"
ui.Title.TextColor = fx.Colors.White
ui.Title.Font = xui.CreateDefaultBoldFont(12)

Puedes modificarlo igual que cualquier Label B4J.


titlestyle

ui.titlestyle(xui.Color_RGB(67, 67, 77))

La implementación aplica al título:

  • fondo degradado;
  • esquinas suaves;
  • sombra;
  • texto en negrita.

Si se utiliza xui.Color_Transparent, el fondo del título queda transparente.


Icono de la aplicación

ui.SetIcon(fx.LoadImage(File.DirAssets, "app.png"))

SetIcon actualiza:

  1. el icono visible de la barra personalizada;
  2. Form.Icon.

La imagen se adapta al ImageView manteniendo proporción.


Botones de la barra superior

Los botones superiores se agregan dinámicamente a hbWindowTopButtons.

AddIconButton

ui.AddIconButton( _
    "settings", _
    Chr(0xE8B8), _
    fx.Colors.White, _
    fx.CreateMaterialIcons(22), _
    ui.ACTION_NONE, _
    "Settings")

Firma:

AddIconButton( _
    EventName As String, _
    IconChar As String, _
    IconColor As Paint, _
    IconFont As Font, _
    Action As Int, _
    ToolTipMsg As String) As Button

El icono se normaliza internamente a un tamaño cercano a 22.

AddImageButton

ui.AddImageButton( _
    "profile", _
    File.DirAssets, _
    "user.png", _
    ui.ACTION_NONE, _
    "Profile")

La imagen se prepara aproximadamente a 22 px.


Acciones incorporadas

Constante Valor Acción
ACTION_NONE -1 No ejecuta una acción de ventana
ACTION_EXIT 2 Finaliza la aplicación
ACTION_MAXIMIZE 4 Maximiza o restaura
ACTION_MINIMIZE 8 Minimiza
ACTION_FULLSCREEN 16 Entra en pantalla completa

Ejemplo:

ui.AddIconButton( _
    "fullscreen", _
    Chr(0xE5D0), _
    fx.Colors.White, _
    fx.CreateMaterialIcons(22), _
    ui.ACTION_FULLSCREEN, _
    "Full screen")

ACTION_EXIT

ACTION_EXIT ejecuta el evento Exiting y después ExitApplication.

No equivale a cerrar únicamente un Form secundario.

Para una ventana secundaria usa ACTION_NONE y desde EventName_Click llama al cierre que necesites.


Eventos de ventana

Si el EventName es ui:

Private Sub ui_Maximizing
End Sub

Private Sub ui_Maximized
End Sub

Private Sub ui_Minimizing
End Sub

Private Sub ui_Minimized
End Sub

Private Sub ui_EnteringFullScreen
End Sub

Private Sub ui_FullScreen
End Sub

Private Sub ui_Exiting
End Sub

También existen los eventos generales de los botones:

Private Sub ui_MouseClicked(ButtonSender As Button, EventData As MouseEvent)
End Sub

Private Sub ui_MouseEntered(ButtonSender As Button, EventData As MouseEvent)
End Sub

Private Sub ui_MouseExited(ButtonSender As Button, EventData As MouseEvent)
End Sub

Y cada botón dinámico puede utilizar su propio:

EventName_Click

Ejemplo:

Private Sub settings_Click
    Log("Settings")
End Sub

Orden visual de los botones

Los botones se insertan en la posición 0 del contenedor.

Si agregas:

close
maximize
minimize

el orden visual habitual termina como:

minimize | maximize | close

Esto permite construir fácilmente la disposición clásica de controles de ventana.


GetButton

Dim Btn As Button = ui.GetButton("settings")
If Btn.IsInitialized Then
    Btn.Disable = True
End If

El Map interno utiliza el EventName entregado al crear el botón.


BarPanel

WindowsStyle crea un panel superior central que puede obtenerse así:

Dim TopArea As B4XView = ui.panelbar

Su altura base es 45 y su ancho se recalcula aproximadamente como un tercio del ancho de la ventana.

Este panel puede usarse para:

  • switch claro / oscuro;
  • selector de modo;
  • estado;
  • búsqueda;
  • acciones rápidas;
  • cualquier B4XView personalizado.

Ejemplo:

Dim TopArea As B4XView = ui.panelbar
TopArea.AddView(MySwitch, 0, 0, 100dip, 35dip)

PanelBarAllowDragging

ui.PanelBarAllowDragging = True

Cuando está activo, el BarPanel también funciona como zona de arrastre de la ventana.


Arrastrar la ventana

apWindowTop permite mover el Form utilizando coordenadas globales del mouse.

El arrastre se bloquea mientras:

  • la ventana está maximizada;
  • se ejecuta una animación.

Resizable

ui.Resizable = True

La implementación actual usa principalmente:

  • borde derecho;
  • borde inferior;
  • esquina inferior derecha.

Mientras la ventana está maximizada, el resize manual queda desactivado.


Límites de tamaño

ui.SetWindowSizeLimits(700, 500, 1800, 1200)

La clase guarda:

  • ancho mínimo;
  • alto mínimo;
  • ancho máximo;
  • alto máximo.

También corrige inmediatamente el Form si ya está fuera del rango.


BorderWidth

Valor inicial interno: 7.

ui.BorderWidth = 8
Log(ui.BorderWidth)

Este valor participa en la geometría de los bordes y del área de contenido.


BorderRadius

Valor inicial interno: 10.

ui.BorderRadius(14)

Se aplica a border-radius y background-radius del RootPane exterior.


Dropshadow

ui.Dropshadow = fx.Colors.Black

Aplica una sombra gaussiana al marco exterior.

La implementación también reduce pbase con un margen interno para que la sombra y las esquinas sean visibles.

Por eso, después de aplicar Dropshadow, una aplicación con layouts muy ajustados debe comprobar el espacio disponible.


Inershadow

El nombre real de la propiedad pública es Inershadow.

ui.Inershadow = fx.Colors.Gray

Aplica un efecto CSS innershadow al RootPane exterior.


ColorUI

ui.ColorUI = fx.Colors.RGB(30, 30, 46)

Cambia el fondo exterior de WindowsStyle.

No debe confundirse con el color del layout que cargues dentro de ui.RootPane.


AlwaysOnTop

ui.AlwaysOnTop = False

En el código actual el valor interno inicial es True y Initialize lo aplica al Stage.

Por tanto, para una ventana de escritorio normal conviene establecer explícitamente:

ui.AlwaysOnTop = False

Animaciones

ui.AnimationsActivated = True
ui.AnimationSpeedMultiplier = 5

WindowsStyle usa un Timer para interpolar:

  • X;
  • Y;
  • ancho;
  • alto;
  • geometría de borde.

La animación se usa principalmente al maximizar y restaurar.


RegisterOnMaximizeComplete

ui.RegisterOnMaximizeComplete(Me)

Public Sub OnMaximizeComplete
    Log("Maximize terminado")
End Sub

Esta notificación ocurre al finalizar la transición hacia maximizado.

Es útil cuando un menú, tabla, editor o layout necesita recalcularse después de que termine físicamente la animación.


Full Screen

ui.AddIconButton( _
    "fullscreen", _
    Chr(0xE5D0), _
    fx.Colors.White, _
    fx.CreateMaterialIcons(22), _
    ui.ACTION_FULLSCREEN, _
    "Full screen")

Flujo:

ui_EnteringFullScreen
→ Stage.setFullScreen(True)
→ ui_FullScreen

WindowsStyle puede reservar automáticamente espacio lateral para un menú.

Constante Valor Reserva lateral
No_menu 0 0
Menu_type_1 1 261
Menu_type_2 2 140
Menu_type_3 3 261

Ejemplo:

ui.MenuType = ui.Menu_type_1

La llamada recalcula RootPane y BarPanel.

Esto permite integrar WindowsStyle con JWindowsMenuStyle sin tener que calcular manualmente el ancho del contenido.


Relación con JWindowsMenuStyle

JWindowsMenuStyle recibe una instancia de jdashboard_WindowsStyle y utiliza MenuType para reservar el espacio correcto.

En otras palabras:

jdashboard_WindowsStyle = ventana y shell
JWindowsMenuStyle       = navegación lateral opcional

Son módulos complementarios, pero WindowsStyle puede usarse sin menú.


AdjustRootPanel

Firma:

AdjustRootPanel(Width As Double, Height As Double, MenuWidth As Int)

Considera:

  • barra superior de 45;
  • margen interno;
  • BorderWidth;
  • ancho reservado por menú.

Normalmente no necesitas llamarlo a mano porque MenuType, resize y SetSizeByPercentage ya actualizan la geometría.


AdjustBarPanel

ui.AdjustBarPanel(MainForm.Width)

Mantiene BarPanel centrado, con aproximadamente un tercio del ancho disponible y 45 de alto.


SetSizeByPercentage

ui.SetSizeByPercentage(75, 86)

Significa:

75 % del ancho de la pantalla
86 % del alto de la pantalla

La ventana se centra automáticamente en la pantalla detectada.

Multi-monitor

La clase registra listeners sobre X y Y del Stage.

Si la ventana fue configurada con SetSizeByPercentage y se mueve a otro monitor, WindowsStyle vuelve a calcular su tamaño usando el mismo porcentaje en la nueva pantalla.

Esto es especialmente útil con monitores de resoluciones distintas.


GetPercentX y GetPercentY

Se basan en TargetWidth y TargetHeight del Form completo.

Dim W As Double = ui.GetPercentX(50)
Dim H As Double = ui.GetPercentY(25)

GetRootPanelPercentX y GetRootPanelPercentY

Se basan en el área visible real de pbase.

Dim W As Double = ui.GetRootPanelPercentX(80)
Dim H As Double = ui.GetRootPanelPercentY(50)

Úsalos cuando haya:

  • barra superior;
  • BorderWidth;
  • MenuType;
  • márgenes internos.

Focused

If ui.Focused Then
    Log("Hay una vista con foco")
End If

La implementación recorre de forma recursiva las vistas del RootPane y comprueba isFocused de JavaFX.


Dispose

ui.Dispose

Libera:

  • Timer;
  • listeners X/Y;
  • Stylesheets;
  • nodos del RootPane;
  • Maps de botones;
  • callbacks de maximize.

Dispose es idempotente.

Es especialmente importante para Forms secundarios que se crean y destruyen sin cerrar toda la aplicación.


TopBarStyle y BorderStyle

La API pública incluye:

Log(ui.TopBarStyle)
Log(ui.BorderStyle)

En la implementación actual las variables internas asociadas se declaran pero no reciben un valor posterior. Por tanto, actualmente estos getters pueden devolver una cadena vacía.

Se documentan porque forman parte de la API pública, pero no deben considerarse una fuente fiable del CSS aplicado.


Lo que WindowsStyle NO hace automáticamente

Para evitar confusiones:

  • no crea un Ribbon;
  • no crea un menú lateral;
  • no crea un dashboard;
  • no crea tablas ni gráficos;
  • no incluye un conjunto cerrado de temas de aplicación;
  • no decide el diseño interior.

Lo que sí hace es proporcionar la ventana moderna sobre la que todos esos componentes pueden montarse.

Los ejemplos visuales de Licensr Pro, LibX Template Studio, B4X Antivirus Pro y DataFlow muestran precisamente esa flexibilidad: misma base de ventana, diseños internos completamente distintos.


API pública completa

Métodos

API Función
Initialize Inicializa WindowsStyle
Dispose Libera recursos
BorderRadius Cambia radio de esquinas
panelbar Devuelve BarPanel
AddIconButton Agrega botón superior con icono
AddImageButton Agrega botón superior con imagen
GetButton Recupera botón por EventName
Focused Busca una vista con foco
SetIcon Define icono de ventana
RegisterOnMaximizeComplete Registra callback al terminar maximize
Title Devuelve Label del título
titlestyle Aplica estilo al título
SetWindowSizeLimits Define límites min/max
AdjustBarPanel Recalcula BarPanel
AdjustRootPanel Recalcula área de contenido
SetSizeByPercentage Tamaño relativo a la pantalla
GetRootPanelPercentX Porcentaje de pbase
GetRootPanelPercentY Porcentaje de pbase
GetPercentX Porcentaje de TargetWidth
GetPercentY Porcentaje de TargetHeight

Propiedades

Propiedad Función
AlwaysOnTop Mantiene el Stage sobre otras ventanas
ColorUI Fondo exterior
PanelBarAllowDragging Permite drag desde BarPanel
Dropshadow Sombra exterior
Inershadow Sombra interior
Resizable Activa resize manual
TopBarStyle Getter de estilo
BorderStyle Getter de estilo
BorderWidth Ancho del marco
AnimationSpeedMultiplier Velocidad de animación
AnimationsActivated Activa / desactiva animaciones
RootPane Área de contenido pbase
MenuType Reserva lateral de menú

Campos públicos

ACTION_EXIT
ACTION_MAXIMIZE
ACTION_MINIMIZE
ACTION_FULLSCREEN
ACTION_NONE

Menu_type_1
Menu_type_2
Menu_type_3
No_menu

hbWindowTopButtons
TargetWidth
TargetHeight

Ejemplo completo recomendado

Sub Process_Globals
    Private fx As JFX
    Private xui As XUI
    Private MainForm As Form
    Private ui As jdashboard_WindowsStyle
End Sub

Sub AppStart(Form1 As Form, Args() As String)
    MainForm = Form1

    ui.Initialize(Me, MainForm, "ui", fx.Colors.RGB(30, 30, 46))

    ui.SetSizeByPercentage(75, 86)
    ui.SetWindowSizeLimits(700, 500, 1800, 1200)

    ui.Title.Text = "My Application"
    ui.Title.TextColor = fx.Colors.White
    ui.Title.Font = xui.CreateDefaultBoldFont(12)

    ui.SetIcon(fx.LoadImage(File.DirAssets, "app.png"))
    ui.titlestyle(xui.Color_RGB(67, 67, 77))

    ui.BorderRadius(10)
    ui.BorderWidth = 7
    ui.Resizable = True
    ui.AnimationsActivated = True
    ui.AnimationSpeedMultiplier = 5
    ui.AlwaysOnTop = False
    ui.MenuType = ui.No_menu

    ui.AddIconButton("close", Chr(0xE14C), fx.Colors.White, _
        fx.CreateMaterialIcons(22), ui.ACTION_EXIT, "Close")

    ui.AddIconButton("maximize", Chr(0xE3E0), fx.Colors.White, _
        fx.CreateMaterialIcons(22), ui.ACTION_MAXIMIZE, "Maximize")

    ui.AddIconButton("minimize", Chr(0xE15B), fx.Colors.White, _
        fx.CreateMaterialIcons(22), ui.ACTION_MINIMIZE, "Minimize")

    ui.AddIconButton("settings", Chr(0xE8B8), fx.Colors.White, _
        fx.CreateMaterialIcons(22), ui.ACTION_NONE, "Settings")

    ui.RegisterOnMaximizeComplete(Me)

    ui.RootPane.LoadLayout("Main")
    MainForm.Show
End Sub

Private Sub settings_Click
    Log("Settings")
End Sub

Private Sub ui_Maximizing
    Log("Maximize / restore requested")
End Sub

Private Sub ui_Minimizing
    Log("Minimize requested")
End Sub

Private Sub ui_Exiting
    Log("Application closing")
End Sub

Public Sub OnMaximizeComplete
    Log("Maximize animation finished")
End Sub

Recomendaciones

  1. Inicializa WindowsStyle antes de cargar el layout principal.
  2. Carga el contenido en ui.RootPane.
  3. Establece AlwaysOnTop = False para ventanas normales.
  4. Usa ACTION_* para controles del sistema.
  5. Usa ACTION_NONE para botones propios.
  6. Mantén EventName consistentes para GetButton.
  7. Usa SetSizeByPercentage en entornos multi-monitor.
  8. Usa GetRootPanelPercentX/Y cuando el layout deba basarse en el área visible real.
  9. Configura MenuType al usar navegación lateral.
  10. Llama Dispose cuando destruyas Forms secundarios.