Visión general
custom_form es una clase auxiliar de jdashboardUI para crear ventanas B4J personalizadas completas utilizando jdashboard_WindowsStyle como motor visual.
No debe entenderse simplemente como un diálogo.
La clase crea un Form nuevo, aplica WindowsStyle, asigna un Owner, prepara un área de contenido y después deja accesibles tanto el Form real como la instancia completa de WindowsStyle. Por eso puede servir para una ventana Acerca de sencilla, pero también para un editor completo con JMenuBar, MonacoEditorView, atajos de teclado, controles propios y redimensionamiento.
La relación real es:
custom_form
↓ crea
Form B4J
↓ aplica
jdashboard_WindowsStyle
↓ expone
panel + RootPane + Form + ui
↓
la aplicación construye la ventana que necesite
El comportamiento inicial favorece una ventana secundaria compacta, pero después de show el desarrollador puede modificar ui y GetForm para convertirla en una herramienta mucho más compleja.
Es útil para:
- Acerca de / About.
- Configuración y preferencias.
- Propiedades.
- Formularios de edición.
- Vista previa.
- Selectores.
- Herramientas auxiliares.
- Editores completos.
- Ventanas con JMenuBar.
- Ventanas con MonacoEditorView.
- Formularios redimensionables.
- Cualquier ventana secundaria que deba conservar la estética de jdashboardUI.
Para la ventana principal de una aplicación también puede reutilizarse, aunque jdashboard_WindowsStyle directo ofrece control más bajo nivel.
Dependencias reales
custom_form utiliza principalmente:
- jdashboard_WindowsStyle.
- jdashboardUtils.
- JFX.
- XUI.
- JavaObject.
La clase expone públicamente:
Public ui As jdashboard_WindowsStyle
Esto significa que después de crear el formulario puedes acceder directamente a prácticamente toda la API de WindowsStyle.
Además de borders y ui, Class_Globals declara sin Private varias variables que las aplicaciones reales usan directamente:
Dim imageicon As Image
Dim colorpanel, colorui As Paint
Dim title As String
Dim panel_round As Int = 5
Dim TitleTextColor As Paint = fx.Colors.White
Por tanto son parte importante de la configuración práctica previa a show:
frm.imageicon = xui.LoadBitmap(File.DirAssets, "icon.png")
frm.colorpanel = fx.Colors.Transparent
frm.colorui = fx.Colors.RGB(30, 30, 46)
frm.title = "My Window"
frm.panel_round = 10
frm.TitleTextColor = fx.Colors.White
frm.borders = 5
Patrón correcto de uso
custom_form trabaja en dos fases:
Initialize
↓
show(...)
↓
Configurar ui / cargar layout / agregar botones
↓
Start
↓
ShowAndWait
La diferencia entre show y Start es importante.
show construye el Form y WindowsStyle.
Start muestra realmente la ventana.
Ejemplo mínimo
Private SettingsForm As custom_form
Private Sub OpenSettings
SettingsForm.Initialize
SettingsForm.show( _
Me, _
"SettingsForm", _
650, _
420, _
MainForm)
SettingsForm.ColorUI = fx.Colors.RGB(30, 30, 46)
SettingsForm.ui.Title.Text = "Settings"
SettingsForm.ui.AlwaysOnTop = False
SettingsForm.panel.LoadLayout("Settings")
SettingsForm.AddButtonIcon( _
"closeSettings", _
Chr(0xE14C), _
fx.Colors.White, _
fx.CreateMaterialIcons(22), _
"Close")
SettingsForm.Start
End Sub
Private Sub closeSettings_Click
SettingsForm.close
End Sub
Initialize
Firma:
Initialize
No recibe parámetros.
Dim Dialog As custom_form
Dialog.Initialize
La creación real del Form ocurre en show.
show
Firma pública:
show( _
callback As Object, _
Eventname As String, _
width As Double, _
height As Double, _
parent As Form)
Ejemplo:
Dialog.show(Me, "Dialog", 700, 500, MainForm)
Durante show, la implementación actual:
- guarda callback y EventName;
- guarda TargetWidth y TargetHeight;
- inicializa un Form nuevo;
- pone el Form en estilo TRANSPARENT;
- inicializa jdashboard_WindowsStyle;
- aplica icono si ya existe;
- asigna el Form principal como Owner;
- configura texto y fuente del título;
- deshabilita resize en WindowsStyle;
- aplica BorderWidth;
- deshabilita animaciones de WindowsStyle;
- aplica jdashboardUtils.customNode sobre el área visible;
- deshabilita resize también en el Form;
- deshabilita MenuType.
Importante: show no llama a Show ni a ShowAndWait.
La ventana todavía no aparece.
Start
Dialog.Start
Internamente ejecuta:
frm.ShowAndWait
Por eso custom_form está orientado principalmente a ventanas modales.
Ejemplo:
Dialog.Start
Log("La ventana ya se cerró")
La siguiente línea se ejecuta cuando ShowAndWait termina.
Owner
Dentro de show se ejecuta:
frm.SetOwner(parent)
Por eso el Form principal debe pasarse como último parámetro.
Esto mantiene la relación correcta entre la ventana principal y el diálogo secundario.
panel
Dim Content As B4XView = Dialog.panel
panel devuelve:
ui.RootPane
Este es el lugar recomendado para cargar el contenido.
Dialog.panel.LoadLayout("Settings")
RootPane
La propiedad RootPane devuelve:
frm.RootPane
No es lo mismo que panel.
Dialog.panel
= ui.RootPane
= área de contenido preparada por WindowsStyle
Dialog.RootPane
= frm.RootPane
= raíz completa del Form
Para layouts normales usa panel.
Utiliza RootPane cuando realmente necesites acceso a la raíz nativa completa.
Form
Dim F As Form = Dialog.Form
La propiedad Form devuelve el Form real creado internamente.
Ejemplo:
Dialog.Form.Title = "Advanced Settings"
Dialog.Form.WindowLeft = 100
Dialog.Form.WindowTop = 100
ui
El campo público ui es una de las partes más útiles de custom_form.
Dialog.ui.Title.Text = "Settings"
Dialog.ui.Title.TextColor = fx.Colors.White
Dialog.ui.BorderRadius(14)
Dialog.ui.Dropshadow = fx.Colors.Black
Dialog.ui.AlwaysOnTop = False
También puedes acceder al BarPanel:
Dim TopArea As B4XView = Dialog.ui.panelbar
Esto permite agregar controles propios a la zona superior.
custom_form es pequeño, pero el acceso a ui permite ampliar la ventana con toda la API de WindowsStyle.
ColorUI
Propiedad exportada:
Dialog.ColorUI = fx.Colors.RGB(32, 36, 48)
Leer:
Dim C As Paint = Dialog.ColorUI
setColorUI guarda el color y llama a ui.ColorUI.
Como ui se inicializa dentro de show, el orden más seguro es:
Dialog.show(...)
Dialog.ColorUI = MyColor
Dialog.Start
borders
Campo público:
Dialog.borders = 8
Durante show se aplica a:
ui.BorderWidth = borders
Por eso conviene configurarlo antes de show:
Dialog.Initialize
Dialog.borders = 8
Dialog.show(Me, "Dialog", 700, 500, MainForm)
El valor inicial es 5.
Resize: estado inicial y personalización
Durante show la clase parte de:
ui.Resizable = False
frm.Resizable = False
Eso es un valor inicial, no una limitación de custom_form.
Después de show puedes activar resize en ambos niveles:
frm.UI.Resizable = True
frm.GetForm.Resizable = True
Una implementación real del editor de manifiestos hace exactamente esto y además accede al Stage para definir un ancho y alto mínimos. Por tanto custom_form puede servir como base para ventanas grandes y redimensionables, no solamente para formularios compactos.
Animaciones de WindowsStyle
Durante show:
ui.AnimationsActivated = False
Esto solo desactiva las animaciones del shell de WindowsStyle.
Los controles que coloques dentro del Form pueden seguir utilizando sus propias animaciones.
Estado inicial del menú lateral
custom_form fuerza inicialmente:
ui.MenuType = ui.no_menu
Esto evita reservar espacio lateral automáticamente al construir la ventana. Como ui queda expuesto públicamente, después de show puedes seguir configurando WindowsStyle según las necesidades de tu aplicación.
Ejemplo real 1 — Acerca de Ribbon UI Studio
Una implementación real configura custom_form antes de show:
frm.Initialize
frm.imageicon = xui.LoadBitmap(File.DirAssets, "addin-office@48px.png")
frm.colorpanel = fx.Colors.Transparent
frm.colorui = fx.Colors.RGB(30, 30, 46)
frm.title = "Acerca de Ribbon UI Studio"
frm.borders = 5
frm.show(Me, "frm", 600dip, 430dip, Parent)
frm.ui.AlwaysOnTop = False
Después utiliza frm.panel como un contenedor normal de jdashboardUI:
Dim img As JImageView = jdashboardUtils.CreateJImageView(150, 150)
img.Load(File.DirAssets, "caracteristica.png")
img.ResizeMode = "FILL_NO_DISTORTIONS"
frm.panel.AddView(img.mBase, 15, 20, 110, 110)
También agrega JTextFlow, un jButton y un botón de cierre mediante AddButtonIcon. Finalmente aplica un degradado global sobre frm.RootPane y llama a frm.Start.
Este ejemplo demuestra que custom_form puede actuar como una ventana de presentación completamente personalizada.
Ejemplo real 2 — editor completo con JMenuBar y Monaco
Otra implementación real utiliza custom_form como shell de un editor de 900 × 650.
Primero configura icono, colores y título:
frm.Initialize
frm.ImageIcon = xui.LoadBitmap(File.DirAssets, "icon.png")
frm.ColorPanel = fx.Colors.From32Bit(xui.Color_ARGB(238, 35, 42, 64))
frm.ColorUI = fx.Colors.From32Bit(xui.Color_ARGB(242, 27, 34, 52))
frm.Title = windowTitle
frm.Show(Me, "frm", 900dip, 650dip, Parent)
Después lo convierte en una ventana redimensionable:
frm.UI.Resizable = True
frm.GetForm.Resizable = True
Y sobre frm.Panel construye una interfaz completa con:
- ContentHost.
- JMenuBar.
- Menús Archivo y Editar.
- MonacoEditorView.
- Barra de estado.
- Atajos de teclado.
- Interceptación del cierre nativo.
- Timer para inicialización.
- Tamaños mínimos del Stage.
Esto demuestra que custom_form no es una clase de diálogo: es un constructor de ventanas personalizadas que utiliza WindowsStyle como base.
AddButtonIcon
Permite agregar botones personalizados a la barra superior.
Dim Btn As Button = Dialog.AddButtonIcon( _
"helpDialog", _
Chr(0xE887), _
fx.Colors.White, _
fx.CreateMaterialIcons(22), _
"Help")
Firma:
AddButtonIcon( _
EventName As String, _
IconChar As String, _
IconColor As Paint, _
IconFont As Font, _
ToolTipMsg As String) As Button
La implementación:
- crea un Button transparente;
- normaliza el icono aproximadamente a tamaño 22;
- agrega Tooltip si se especifica;
- crea handlers JavaFX mediante JavaObject;
- inserta el botón en ui.hbWindowTopButtons;
- devuelve el Button.
AddButtonImage
Dim Btn As Button = Dialog.AddButtonImage( _
"profileDialog", _
File.DirAssets, _
"user.png", _
"Profile")
Firma:
AddButtonImage( _
EventName As String, _
FileDir As String, _
FileName As String, _
ToolTipMsg As String) As Button
La imagen se aplica mediante jdashboardUtils.ButtonSetImage.
Orden de los botones
Los botones se insertan en:
ui.hbWindowTopButtons
mediante:
Buttons.InsertAt(0, btn)
Cada nuevo botón se coloca antes que los anteriores.
Eventos Click
El EventName de cada botón se usa para formar:
EventName_Click
Ejemplo:
Dialog.AddButtonIcon( _
"helpDialog", _
Chr(0xE887), _
fx.Colors.White, _
fx.CreateMaterialIcons(22), _
"Help")
Evento:
Private Sub helpDialog_Click
Log("Help")
End Sub
La clase utiliza JavaObject para capturar el evento JavaFX y después lo reenvía al callback de show.
Eventos Hover
También se reenvían eventos individuales:
EventName_MouseEntered
EventName_MouseExited
Ejemplo:
Private Sub helpDialog_MouseEntered( _
ButtonSender As Button, _
EventData As MouseEvent)
ButtonSender.Opacity = 0.8
End Sub
Private Sub helpDialog_MouseExited( _
ButtonSender As Button, _
EventData As MouseEvent)
ButtonSender.Opacity = 1
End Sub
Cerrar el formulario
Dialog.close
La implementación:
- comprueba si ui está inicializado;
- llama ui.Dispose;
- ejecuta frm.Close.
Además frm_Close también llama ui.Dispose.
Esto evita dejar recursos o listeners de WindowsStyle activos.
Botón Close recomendado
Para una ventana secundaria no conviene utilizar ACTION_EXIT de WindowsStyle, ya que ACTION_EXIT finaliza toda la aplicación.
El patrón seguro es:
Dialog.AddButtonIcon( _
"closeDialog", _
Chr(0xE14C), _
fx.Colors.White, _
fx.CreateMaterialIcons(22), _
"Close")
Private Sub closeDialog_Click
Dialog.close
End Sub
SetSizeByPercentage
Dialog.SetSizeByPercentage(60, 70)
La implementación:
- obtiene fx.Screens;
- intenta localizar la pantalla donde se encuentra el centro del Form;
- usa PrimaryScreen como fallback;
- calcula ancho y alto según porcentaje;
- centra el Form en esa pantalla;
- actualiza TargetWidth y TargetHeight.
Ejemplo:
Dialog.show(Me, "Preview", 800, 600, MainForm)
Dialog.SetSizeByPercentage(70, 75)
Dialog.panel.LoadLayout("Preview")
Dialog.Start
GetPercentX / GetPercentY
Dim W As Double = Dialog.GetPercentX(50)
Dim H As Double = Dialog.GetPercentY(25)
Se calculan sobre TargetWidth y TargetHeight.
Estos valores se actualizan:
- durante show;
- cuando frm recibe Resize;
- después de SetSizeByPercentage.
Ejemplo completo: Settings
Private SettingsDialog As custom_form
Private Sub btnSettings_Click
SettingsDialog.Initialize
SettingsDialog.borders = 6
SettingsDialog.show( _
Me, _
"SettingsDialog", _
720, _
480, _
MainForm)
SettingsDialog.ColorUI = fx.Colors.RGB(24, 28, 40)
SettingsDialog.ui.Title.Text = "Application Settings"
SettingsDialog.ui.Title.TextColor = fx.Colors.White
SettingsDialog.ui.BorderRadius(12)
SettingsDialog.ui.AlwaysOnTop = False
SettingsDialog.AddButtonIcon( _
"aboutSettings", _
Chr(0xE88E), _
fx.Colors.White, _
fx.CreateMaterialIcons(22), _
"About")
SettingsDialog.AddButtonIcon( _
"closeSettings", _
Chr(0xE14C), _
fx.Colors.White, _
fx.CreateMaterialIcons(22), _
"Close")
SettingsDialog.panel.LoadLayout("Settings")
SettingsDialog.Start
End Sub
Private Sub aboutSettings_Click
Log("About")
End Sub
Private Sub closeSettings_Click
SettingsDialog.close
End Sub
Variables accesibles que el extractor no enumera
El metadata de module_public_elements enumera explícitamente como fields:
borders
ui
Sin embargo, el código fuente declara también sin Private:
Dim imageicon As Image
Dim colorpanel, colorui As Paint
Dim title As String
Dim panel_round As Int = 5
Dim TitleTextColor As Paint = fx.Colors.White
Y aplicaciones reales las utilizan directamente desde fuera de la clase.
Por tanto no deben tratarse como variables internas. Son parte de la configuración práctica de custom_form, aunque el extractor JSON actual no las liste como field.
La fuente también contiene:
Sub setFormIcon(image As Image)
pero este helper no está declarado Public. Para cambiar el icono desde fuera, usa imageicon antes de show o ui.SetIcon / GetForm.Icon después de show.
API pública exportada
Métodos
| API | Función |
|---|---|
| Initialize | Inicializa custom_form |
| show | Crea y prepara el Form |
| Start | Ejecuta ShowAndWait |
| panel | Devuelve ui.RootPane |
| close | Libera WindowsStyle y cierra |
| AddButtonImage | Agrega botón superior con imagen |
| AddButtonIcon | Agrega botón superior con icono |
| GetPercentX | Porcentaje de TargetWidth |
| GetPercentY | Porcentaje de TargetHeight |
| SetSizeByPercentage | Tamaño según pantalla |
Propiedades
| Propiedad | Tipo | Uso |
|---|---|---|
| ColorUI | Paint | Color de WindowsStyle |
| RootPane | AnchorPane | RootPane nativo |
| Form | Form | Form real |
Campos y configuración directa
| Campo / variable | Tipo | Uso |
|---|---|---|
| borders | Int | BorderWidth aplicado durante show |
| ui | jdashboard_WindowsStyle | Acceso completo al motor de ventana |
| imageicon | Image | Icono aplicado al Form y a WindowsStyle |
| colorpanel | Paint | Fondo del área interna |
| colorui | Paint | Color base entregado a WindowsStyle |
| title | String | Título del Form y de la barra |
| panel_round | Int | Radio aplicado por customNode |
| TitleTextColor | Paint | Color inicial del título |
custom_form vs jdashboard_WindowsStyle
| custom_form | jdashboard_WindowsStyle |
|---|---|
| crea un Form nuevo | estiliza un Form existente |
| orientado a ventanas secundarias | motor general de ventanas |
| Owner incorporado | Owner lo maneja la aplicación |
| Start usa ShowAndWait | el desarrollador elige Show |
| parte no resizable, pero puede habilitarse después de show | resizable configurable |
| sin menú | MenuType configurable |
| animaciones desactivadas | animaciones configurables |
| API compacta | API completa |
| expone ui | es el motor base |
WindowsStyle es el motor. custom_form es el constructor práctico de ventanas B4J completas basadas en ese motor. No es simplemente un diálogo.