Visión general
Ribbon UI no es un solo control. En jdashboardUI es una familia completa de clases que trabajan juntas para construir una interfaz tipo Microsoft Office en B4J.
La estructura real es:
Ribbon
├── Quick Access Bar
├── RibbonTab
│ ├── RibbonGroup
│ │ ├── botones grandes
│ │ ├── RibbonMenu
│ │ ├── RibbonButtonGroup
│ │ └── RibbonSmartButtonGroup
│ └── más RibbonGroup...
└── más RibbonTab...
También existen RibbonQuickAccess, para acceso avanzado al Quick Access Bar nativo, y GradientPanel, como utilidad visual opcional. GradientPanel no es una dependencia obligatoria del Ribbon.
Las capturas de Ribbon UI Studio, FirmaDoc Pro y aplicaciones con tablas sirven aquí únicamente como referencia de uso. Esta documentación se basa en el código fuente real.
Qué pertenece al Ribbon y qué no
El Ribbon se encarga de pestañas, grupos, botones, grupos compactos, menús, submenús, Quick Access, temas, colores, fuentes y eventos de pestañas.
La barra de título de la ventana, el nombre de la aplicación, minimizar / maximizar / cerrar, la tabla, el editor, el visor PDF y la barra de estado pertenecen a la aplicación que contiene el Ribbon. Ribbon no los crea automáticamente.
Módulos de Ribbon UI
| Módulo | Función |
|---|---|
| Ribbon | Control principal, tabs, Quick Access, temas y estilos globales |
| RibbonTab | Una pestaña como Home, Tools o Help |
| RibbonGroup | Grupo grande dentro de una pestaña |
| RibbonButtonGroup | Grupo compacto con icono + texto |
| RibbonSmartButtonGroup | Grupo compacto normalmente solo icono |
| RibbonMenu | Menús, checks, radio items, títulos, paneles y submenús |
| RibbonQuickAccess | Wrapper avanzado del QuickAccessBar Java |
| GradientPanel | Fondo degradado opcional |
Dependencia Java principal
El proyecto fuente declara:
#AdditionalJar: fxribbon-1.2.2.jar
Las clases crean directamente:
com.pixelduke.control.Ribbon
com.pixelduke.control.ribbon.RibbonTab
com.pixelduke.control.ribbon.RibbonGroup
com.pixelduke.control.ribbon.QuickAccessBar
Al compilar desde fuente debe estar disponible fxribbon-1.2.2.jar.
Librerías usadas
La implementación usa principalmente jFX, XUI / jXUI, JavaObject, jReflection, CSSUtils, jdashboardUtils y JImageView.
Para el uso normal no necesitas manipular JavaObject ni Reflector porque Ribbon encapsula esas llamadas.
Cómo se usa realmente
El Ribbon principal se recomienda desde el Designer
Ribbon tiene DesignerCreateView y está preparado para utilizarse como Custom View.
A diferencia de otros componentes, el Ribbon principal no expone un AddToParent público. El patrón normal es:
- Agregar Ribbon al layout desde el Designer.
- Cargar el layout.
- Crear RibbonTab desde código.
- Crear RibbonGroup.
- Agregar botones, grupos compactos o RibbonMenu.
- Agregar grupos al tab.
- Agregar tabs al Ribbon.
Ejemplo mínimo
Supongamos que el Custom View se llama Ribbon1.
Sub Class_Globals
Private fx As JFX
Private xui As XUI
Private Ribbon1 As Ribbon
End Sub
Private Sub BuildRibbon
Dim HomeTab As RibbonTab
HomeTab.Initialize(Me, "HomeTab", "Home")
Dim FileGroup As RibbonGroup
FileGroup.Initialize(Me, "File")
FileGroup.AddButtonImage( _
"OpenFile", _
File.DirAssets, _
"open.png", _
"Open File", _
"Open an existing document")
FileGroup.AddButtonIcon( _
"SaveFile", _
fx.CreateFontAwesome(34), _
Chr(0xF0C7), _
xui.Color_RGB(40, 120, 220), _
"Save", _
"Save the current document")
HomeTab.addGroup(FileGroup)
Ribbon1.AddTab(HomeTab)
End Sub
Private Sub OpenFile_Click
Log("Open")
End Sub
Private Sub SaveFile_Click
Log("Save")
End Sub
El EventName de cada botón define directamente la Sub. Por ejemplo:
EventName = OpenFile
evento = OpenFile_Click
Implementación real — Ribbon UI Studio / Office Editor
La mejor forma de entender Ribbon es verlo funcionando dentro de una aplicación grande. Ribbon UI Studio / Office Editor utiliza al mismo tiempo RibbonTab, RibbonGroup, RibbonButtonGroup, RibbonSmartButtonGroup, RibbonMenu, submenús, Quick Access, localización, estados contextuales y funciones Pro.
Configuración real en el Designer
Ribbon1 está colocado como Custom View dentro de Layout1 y usa:
Stylebar = GlassMinimal
BackgroundColor = 0xEB15171B
GroupTextColor = 0xFFE5E5E5
SelectionColor = 0xFF448FB3
SeparatorColor = 0xFF454547
TapTextColor = 0xFFB3B7D5
Height = 220
Horizontal = ancho completo
El área de trabajo se coloca debajo del Ribbon:
MonacoEditorView1.Top = Ribbon1.Bottom + 10
MonacoEditorView1.Height = 100%y - Ribbon1.Height - 45dip
Este es un patrón realista: Ribbon funciona como cabecera fija y el contenido utiliza el espacio restante.
Jerarquía real de la aplicación
Inicio
├── Archivo
│ ├── Abrir
│ ├── Nuevo complemento ▼
│ ├── Guardar
│ ├── Guardar como
│ ├── Empaquetar
│ └── Cerrar documento
└── Iconos
Herramientas
├── Herramientas XML
├── Revisar Ribbon
│ ├── RibbonButtonGroup
│ └── Formatear
├── Gestión de Módulos
│ ├── RibbonButtonGroup
│ └── botones grandes
└── Edición
├── RibbonSmartButtonGroup
└── botones grandes
Licencia ← solo Pro
Ejemplos
Ayuda
Esto muestra que los distintos tamaños de controles se mezclan dentro de una misma cinta.
Reconstruir completamente el Ribbon
La aplicación empieza Ribbon_start limpiando el contenido anterior:
Sub Ribbon_start
Ribbon1.RemoveAllTabs
Ribbon1.RemoveAllQuickAccessButtons
' reconstruir tabs, grupos, menús y Quick Access
End Sub
Este patrón se usa porque la cinta cambia cuando cambia el idioma o la licencia.
Después de activar Pro:
Sub GestorLicencia_ActivationSuccess(Result As LicenseResult)
ValidarNivelLicenciaOfficeEditor
Ribbon_start
ActualizarBotonesArchivo(mFileManager.IsOpen)
Dim isXml As Boolean = mEditorMode <> "vba"
ActualizarBotonesHerramientas( _
mFileManager.IsOpen And isXml, _
isXml)
End Sub
Localización de tabs, grupos, botones y tooltips
tapInicio.Initialize( _
Me, _
"", _
loc.LocalizeTag("tab_home", "Inicio"))
grpArchivo.Initialize( _
Me, _
loc.LocalizeTag("grp_file", "Archivo"))
grpArchivo.AddButtonIcon( _
"btnOpen", _
iconfont.IconFontAwesomeRegular, _
Chr(0xf07c), _
xui.Color_RGB(255, 170, 0), _
loc.LocalizeTag("btn_open", "Abrir"), _
loc.LocalizeTag("tooltip_open", "Abre un archivo de Office"))
Al cambiar idioma se fuerza el locale y se llama nuevamente a Ribbon_start. Esto evita mantener manualmente cada caption.
Botón grande de RibbonGroup
grpArchivo.AddButtonIcon( _
"btnSave", _
iconfont.IconFontAwesomeSolid, _
Chr(0xf0c7), _
xui.Color_RGB(16, 185, 129), _
"Guardar", _
"Guardar los cambios del archivo")
También puede utilizar imagen:
grpHerramientas.AddButtonImage( _
"btnGenerarCallbacks", _
File.DirAssets, _
"file-type-vba@48px.png", _
"Generar callbacks", _
"Crea las macros necesarias")
Estos son los comandos principales y visualmente más grandes.
RibbonMenu grande
Un RibbonMenu puede ocupar el lugar visual de un botón grande:
Dim menuAddin As RibbonMenu
menuAddin.Initialize(Me, "menuAddin")
menuAddin.InitializeGroup("Nuevo complemento")
menuAddin.CreateWithImage( _
File.DirAssets, _
"addin-office@48px.png", _
"Nuevo complemento")
grpArchivo.AddRibbonMenu(menuAddin)
Submenús reales
Office Editor crea menús diferentes para Excel, Word y PowerPoint:
Dim menuExcel As JavaObject = menuAddin.AddSubMenu( _
"subExcelAddin", _
"Excel (.xlam)", _
Chr(0xf1c3), _
iconfont.IconFontAwesomeSolid, _
xui.Color_RGB(35, 114, 41))
menuAddin.AddItemToSubMenu( _
menuExcel, _
"btnCrearExcelAddinModern", _
"Office moderno (2010+)", _
Chr(0xf109), _
iconfont.IconFontAwesomeSolid, _
xui.Color_RGB(35, 114, 41))
RibbonMenu por tanto puede ser un árbol de comandos y no solo un dropdown plano.
RibbonButtonGroup real
En Revisar Ribbon se agrupan tres acciones secundarias:
subgrpRevision.Initialize(Me, "subgrpRevision")
subgrpRevision.AddButtonIcon( _
"btnPreviewRibbon", _
iconfont.IconFontAwesomeSolid, _
Chr(0xf06e), _
fx.Colors.RGB(100, 150, 255), _
"Diseñador visual", _
"Diseña el Ribbon visualmente")
subgrpRevision.AddButtonIcon( _
"btnInspectRibbon", _
iconfont.IconFontAwesomeSolid, _
Chr(0xf0f3), _
fx.Colors.RGB(255, 170, 0), _
"Diagnóstico", _
"Comprueba callbacks, IDs e iconos")
subgrpRevision.AddButtonImage( _
"btnValidate", _
File.DirAssets, _
"file-xml@48px.png", _
"Validar XML", _
"Verifica la sintaxis")
grpRevision.addButtonGroup(subgrpRevision)
Este es un ejemplo real del formato compacto de tres filas.
RibbonSmartButtonGroup real
Copy, Cut y Paste se mantienen todavía más compactos:
subgrpEditar.Initialize(Me, "subgrpEditar")
subgrpEditar.AddButtonIcon( _
"btnEditCopy", _
iconfont.IconFontAwesomeSolid, _
Chr(0xf0c5), _
fx.Colors.RGB(96, 165, 250), _
"Copia el texto seleccionado")
subgrpEditar.AddButtonIcon( _
"btnEditCut", _
iconfont.IconFontAwesomeSolid, _
Chr(0xf0c4), _
fx.Colors.RGB(248, 113, 113), _
"Corta el texto seleccionado")
subgrpEditar.AddButtonIcon( _
"btnEditPaste", _
iconfont.IconFontAwesomeSolid, _
Chr(0xf0ea), _
fx.Colors.RGB(74, 222, 128), _
"Pega el texto del portapapeles")
grpEditar.addSmartButtonGroup(subgrpEditar)
En este modo el texto actúa como tooltip y el icono ocupa el espacio principal.
Diferencia práctica entre tamaños
| Control | Uso real |
|---|---|
| RibbonGroup.AddButtonIcon / AddButtonImage | Acción principal grande |
| RibbonMenu.InitializeGroup | Acción principal grande con dropdown |
| RibbonButtonGroup | Tres comandos compactos con icono o imagen + texto |
| RibbonSmartButtonGroup | Tres comandos muy compactos, principalmente iconos |
| Quick Access | Botones pequeños siempre disponibles |
Guardar el Button devuelto
AddButtonIcon devuelve un Button y la aplicación conserva la referencia cuando necesita controlarlo después:
mPackagingButton = grpArchivo.AddButtonIcon( _
"btnCreateInstaller", _
iconfont.IconFontAwesomeSolid, _
Chr(0xf019), _
xui.Color_RGB(137, 180, 250), _
"Empaquetar", _
"Crea un instalador .exe")
Esto permite modificar Enabled, Visible o Managed directamente.
Enabled según el contexto
grpArchivo.SetButtonEnabled("btnSaveAs", Habilitado)
subgrpRevision.SetButtonEnabled( _
"btnValidate", _
Habilitado And IsXml)
grpRevision.SetButtonEnabled( _
"btnFormat", _
Habilitado And IsXml)
La cinta puede reflejar en tiempo real si hay documento abierto y si el editor está trabajando con XML o VBA.
Ocultar un botón sin dejar espacio vacío
Visible=False puede no ser suficiente cuando quieres que el layout deje de reservar espacio.
La aplicación usa:
Private Sub SetRibbonButtonVisibility( _
b As Button, _
Visible As Boolean)
If b.IsInitialized = False Then Return
b.Visible = Visible
Dim node As JavaObject = b
node.RunMethod("setManaged", Array(Visible))
End Sub
La combinación recomendada es:
Visible = False
Managed = False
De esta manera el Ribbon reorganiza los controles restantes.
Tabs e items condicionales
Un item Pro solo se crea cuando corresponde:
If IsOfficeEditorPro Then
menuNewRibbon.AddItemToSubMenu( _
subTemplates, _
"btnTemplateLicense", _
"Complemento con licencia", _
Chr(0xf084), _
iconfont.IconFontAwesomeSolid, _
xui.Color_RGB(255, 170, 0))
End If
Y una pestaña completa puede ser condicional:
Ribbon1.addTab(tapInicio)
Ribbon1.addTab(tapDesarrollo)
If IsOfficeEditorPro Then
Ribbon1.addTab(tapSeguridad)
End If
Ribbon1.addTab(tapEjemplos)
Ribbon1.addTab(tapAyuda)
Quick Access reutilizando el mismo evento
Ribbon1.AddQuickAccessButtonIcon( _
"btnOpen", _
iconfont.IconFontAwesomeRegular, _
Chr(0xf07c), _
xui.Color_RGB(255, 170, 0), _
"Abrir")
Ribbon1.AddQuickAccessButtonIcon( _
"btnSave", _
iconfont.IconFontAwesomeSolid, _
Chr(0xf0c7), _
xui.Color_RGB(16, 185, 129), _
"Guardar")
Los mismos EventName ya existen en los botones grandes.
Por tanto:
botón grande btnOpen ─┐
├── btnOpen_Click
Quick Access btnOpen ─┘
No se duplica la lógica de eventos.
Quick Access también puede ser contextual
mDesignerQuickButton = _
Ribbon1.AddQuickAccessButtonIcon( _
"btnPreviewRibbon", _
iconfont.IconFontAwesomeSolid, _
Chr(0xf06e), _
xui.Color_RGB(100, 150, 255), _
"Diseñador visual")
Después:
mDesignerQuickButton.Visible = mFileManager.IsOpen
mDesignerQuickButton.Enabled = mFileManager.IsOpen
Dim quickNode As JavaObject = mDesignerQuickButton
quickNode.RunMethod( _
"setManaged", _
Array(mFileManager.IsOpen))
Fuente global después de construir la cinta
Ribbon1.UpdateAllRibbonFonts( _
fx.LoadFont( _
File.DirAssets, _
"righteous-regular.ttf", _
12))
Aplicarla al final garantiza que los controles recién creados también cambien.
Accent contextual según Office
Office Editor adapta el accent del Ribbon al documento abierto:
sin documento → violeta
Word → azul
PowerPoint → naranja
Excel → verde
La llamada utilizada es:
Ribbon1.SetSelectColor(accent)
La aplicación cambia además su barra de título, fondo y barra de estado. Ribbon forma parte de un tema coordinado, pero no necesita controlar toda la ventana.
Patrón de producción recomendado
Designer
↓
Ribbon_start
↓
crear tabs
↓
crear grupos
↓
agregar botones / menus / compact groups
↓
agregar tabs al Ribbon
↓
aplicar fuente global
↓
crear Quick Access
↓
actualizar Enabled / Visible / Managed
Este flujo refleja una implementación real de Ribbon en una aplicación de escritorio compleja.
Ribbon — control principal
Inicialización y eventos generales
Cuando Ribbon está en el Designer, B4J llama a Initialize(Callback, EventName). El EventName del Custom View se usa para eventos globales como:
Ribbon1_TabChanged
Ribbon1_TabThemeChanged
Propiedades del Designer
| Propiedad | Inicial | Uso |
|---|---|---|
| Stylebar | Office2007 | Tema CSS inicial |
| BackgroundColor | 0xFFEFEFEF | Fondo de grupos |
| SelectionColor | 0xFF7866E1 | Color de selección / accent |
| TapTextColor | 0xFF4b4b4b | Texto de pestañas |
| GroupTextColor | 0xFF34373E | Títulos de grupos |
| ButtonTextColor | 0xFF1C1C1C | Texto de controles |
| SeparatorColor | 0xFFD3D3D3 | Separadores |
El nombre real de la propiedad es TapTextColor, igual que en el código fuente.
Temas incorporados
Theme acepta estos nombres exactos:
Office2007
Office2019
Office2021
Modern
FluentFusion
NeonTheme
FluentDesing
FlatRibbon
GlassMinimal
MidnightGlass
NordicLight
Aurora
Ejemplo:
Ribbon1.Theme = Ribbon1.ThemeOffice2021
o:
Ribbon1.Theme = "Office2021"
Tema actual:
Log(Ribbon1.CurrentTheme)
Cambiar colores en ejecución
Ribbon1.ColorGroup = xui.Color_RGB(245, 245, 245)
Ribbon1.TitleGroupColor = xui.Color_DarkGray
Ribbon1.ColorLabelControls = xui.Color_Black
Ribbon1.SelectColor = xui.Color_RGB(35, 170, 110)
Ribbon1.TitleTapColor = xui.Color_DarkGray
Ribbon1.SeparatorColor = xui.Color_LightGray
Cada setter actualiza el estilo del Ribbon.
Cambiar la fuente completa
Dim AppFont As B4XFont = xui.CreateDefaultFont(13)
Ribbon1.UpdateAllRibbonFonts(AppFont)
El recorrido incluye tabs, grupos, RibbonButtonGroup y RibbonMenu registrados.
Eventos del Ribbon
TabChanged
Private Sub Ribbon1_TabChanged(Index As Int, TabName As String)
Log("Tab: " & Index & " - " & TabName)
End Sub
El índice entregado por la implementación es 1-based.
TabThemeChanged
Private Sub Ribbon1_TabThemeChanged(ThemeName As String)
Log("Tema: " & ThemeName)
End Sub
Se dispara desde los handlers internos de selección de tema.
RibbonTab
RibbonTab representa una pestaña superior, por ejemplo Home, Database, Themes, Tools, License o Help.
Crear
Dim ToolsTab As RibbonTab
ToolsTab.Initialize(Me, "ToolsTab", "Tools")
Ribbon1.AddTab(ToolsTab)
Firma real:
Initialize(Callback As Object, EventName As String, Title As String) As RibbonTab
El EventName se almacena, aunque la implementación actual no declara eventos públicos propios del RibbonTab.
Agregar grupo
Dim ToolsGroup As RibbonGroup
ToolsGroup.Initialize(Me, "Tools")
ToolsTab.addGroup(ToolsGroup)
Icono de fuente
ToolsTab.SetTabIcon( _
fx.CreateFontAwesome(18), _
Chr(0xF0AD), _
xui.Color_RGB(60, 120, 220))
Imagen
ToolsTab.SetTabImage(File.DirAssets, "tools.png")
La implementación crea un JImageView de 20 x 20.
Fondo
ToolsTab.BackgroundColor(fx.Colors.White)
Obtener grupos
Dim Groups As List = ToolsTab.GetGroupsList
Acceso avanzado
Dim NativeTab As JavaObject = ToolsTab.AsJO
Dim TabNode As Node = ToolsTab.AsNode
Dim BasePane As Pane = ToolsTab.GetBase
Dim RootSplit As SplitPane = ToolsTab.SplitPane
También existe:
ToolsTab.SetDefaultUserAgentStylesheet
y el helper IsMenuButton(View) para detectar un MenuButton JavaFX.
RibbonGroup
RibbonGroup es una sección visual dentro del tab, por ejemplo File, Clipboard, Editing, Tools, PDF, Images o Alignment.
Crear
Dim FileGroup As RibbonGroup
FileGroup.Initialize(Me, "File")
HomeTab.addGroup(FileGroup)
Firma:
Initialize(Callback As Object, Title As String) As RibbonGroup
El segundo parámetro es el título, no un EventName.
Botón grande con imagen
FileGroup.AddButtonImage( _
"OpenFile", _
File.DirAssets, _
"open.png", _
"Open File", _
"Open an existing file")
Firma:
AddButtonImage(EventName, ImageDir, ImageName, ButtonText = "", Tooltip = "") As Button
Los botones grandes usan una altura visual común de 105dip. El área de imagen se normaliza aproximadamente a 38dip.
Botón grande con icono
FileGroup.AddButtonIcon( _
"SaveFile", _
fx.CreateFontAwesome(34), _
Chr(0xF0C7), _
xui.Color_RGB(40, 120, 220), _
"Save", _
"Save changes")
Evento:
Private Sub SaveFile_Click
End Sub
Cambiar título
FileGroup.addTitle("Document")
Icono junto al título
FileGroup.SetGroupIcon( _
fx.CreateFontAwesome(16), _
Chr(0xF07C), _
xui.Color_RGB(245, 170, 20))
Imagen junto al título
FileGroup.SetGroupImage(File.DirAssets, "folder.png")
Importante
SetGroupIcon y SetGroupImage buscan el Label interno creado por el Skin JavaFX. Si todavía no existe, el código espera 100 ms y vuelve a intentarlo. Es preferible usarlos cuando el Ribbon ya está en escena o después de mostrar el formulario.
Colores locales
FileGroup.TitlesColor(fx.Colors.Blue)
FileGroup.ColorLabelcontrol(fx.Colors.DarkGray)
FileGroup.BackgroundColor(fx.Colors.White)
Obtener un botón
Dim SaveButton As Button = FileGroup.GetButton("SaveFile")
If SaveButton.IsInitialized Then SaveButton.Text = "Save now"
Enabled / Visible
FileGroup.SetButtonEnabled("SaveFile", False)
FileGroup.SetButtonVisible("SaveFile", False)
Agregar una vista propia
FileGroup.addView(MyCustomView)
AddToParent
RibbonGroup sí expone:
FileGroup.AddToParent(ParentPane, 0, 0, 300dip, 120dip)
Para el uso normal dentro del Ribbon se recomienda Tab.addGroup(Group).
Acceso avanzado
Dim NativeGroup As JavaObject = FileGroup.AsJO
Dim NodeGroup As Node = FileGroup.AsNode
Dim BaseGroup As Pane = FileGroup.GetBase
Dim RootSplit As SplitPane = FileGroup.SplitPane
Dim Count As Int = FileGroup.NodeCount
RibbonButtonGroup
RibbonButtonGroup está pensado para comandos compactos con icono + texto como Cut, Copy, Paste Special o comandos de edición.
La implementación organiza tres elementos por columna. Al agregar más de tres, crea otra columna.
Crear
Dim ClipboardButtons As RibbonButtonGroup
ClipboardButtons.Initialize(Me, "ClipboardButtons")
ClipboardButtons.AddButtonIcon( _
"Cut", _
fx.CreateFontAwesome(21), _
Chr(0xF0C4), _
fx.Colors.Blue, _
"Cut", _
"Cut selected content")
ClipboardButtons.AddButtonIcon( _
"Copy", _
fx.CreateFontAwesome(21), _
Chr(0xF0C5), _
fx.Colors.Gray, _
"Copy", _
"Copy selected content")
ClipboardGroup.addButtonGroup(ClipboardButtons)
Con imagen
ClipboardButtons.AddButtonImage( _
"Paste", _
File.DirAssets, _
"paste.png", _
"Paste", _
"Paste content")
Distribución real
- 30dip de altura de fila;
- 3 filas por columna;
- ancho mínimo aproximado 125dip;
- ancho calculado según caption;
- ancho máximo por columna 175dip;
- más de 3 elementos crea nuevas columnas.
Obtener / desactivar
Dim B As Button = ClipboardButtons.GetButton("Copy")
ClipboardButtons.SetButtonEnabled("Copy", False)
Fuente
ClipboardButtons.UpdateFont(xui.CreateDefaultFont(12))
RibbonSmartButtonGroup
RibbonSmartButtonGroup es el formato más compacto. Está pensado principalmente para iconos pequeños centrados.
Crear
Dim AlignButtons As RibbonSmartButtonGroup
AlignButtons.Initialize(Me, "AlignButtons")
AlignButtons.AddButtonIcon( _
"AlignLeft", _
fx.CreateFontAwesome(20), _
Chr(0xF036), _
fx.Colors.DarkGray, _
"Align left")
AlignButtons.AddButtonIcon( _
"AlignCenter", _
fx.CreateFontAwesome(20), _
Chr(0xF037), _
fx.Colors.DarkGray, _
"Align center")
AlignmentGroup.addSmartButtonGroup(AlignButtons)
Con imagen
AlignButtons.AddButtonImage( _
"Grid", _
File.DirAssets, _
"grid.png", _
"Grid view")
Distribución real
- aproximadamente 35dip por botón;
- 30dip de alto;
- 3 elementos por columna;
- una nueva columna cada tres elementos;
- la siguiente columna avanza 40dip.
Estado
AlignButtons.SetButtonEnabled("Grid", False)
Dim GridButton As Button = AlignButtons.GetButton("Grid")
RibbonMenu
RibbonMenu crea un MenuButton JavaFX adaptado al Ribbon.
Tiene tres modos:
- grande en RibbonGroup;
- compacto en RibbonButtonGroup;
- compacto smart en RibbonSmartButtonGroup.
Inicialización base
Dim PasteMenu As RibbonMenu
PasteMenu.Initialize(Me, "PasteMenu")
El EventName del objeto se almacena, pero los eventos de los items se resuelven por el EventName individual de cada item.
RibbonMenu grande
PasteMenu.InitializeGroup("Paste")
Crear con icono
PasteMenu.CreateWithIcon( _
Chr(0xF0EA), _
fx.CreateFontAwesome(34), _
xui.Color_RGB(50, 120, 230), _
"Paste options")
Crear con imagen
PasteMenu.CreateWithImage( _
File.DirAssets, _
"paste.png", _
"Paste options")
Agregarlo:
ClipboardGroup.AddRibbonMenu(PasteMenu)
Los RibbonMenu grandes comparten la altura visual de 105dip con los botones grandes de RibbonGroup.
RibbonMenu compacto
En RibbonButtonGroup
Dim OptionsMenu As RibbonMenu
OptionsMenu.Initialize(Me, "OptionsMenu")
OptionsMenu.InitializeButtonGroup("Options")
OptionsMenu.CreateWithIcon(Chr(0xF013), fx.CreateFontAwesome(21), xui.Color_DarkGray, "Options")
ClipboardButtons.AddRibbonMenu(OptionsMenu)
En RibbonSmartButtonGroup
Dim SmallMenu As RibbonMenu
SmallMenu.Initialize(Me, "SmallMenu")
SmallMenu.InitializeSmartButtonGroup
SmallMenu.CreateWithIcon(Chr(0xF0D7), fx.CreateFontAwesome(20), xui.Color_DarkGray, "More")
AlignButtons.AddRibbonMenu(SmallMenu)
Items de RibbonMenu
Item normal
PasteMenu.AddItem( _
"PastePlain", _
"Paste plain text", _
Chr(0xF0EA), _
fx.CreateFontAwesome(20), _
xui.Color_RGB(60, 120, 220))
Evento:
Private Sub PastePlain_Click
End Sub
Los parámetros de icono son opcionales:
PasteMenu.AddItem("AdvancedPaste", "Advanced Options")
Item con imagen
PasteMenu.AddItemImage( _
"PasteImage", _
"Paste as image", _
File.DirAssets, _
"image.png")
Separador
PasteMenu.AddSeparator
Título con icono
PasteMenu.AddTitle( _
"Paste Options", _
xui.Color_DarkGray, _
Chr(0xF0EA), _
fx.CreateFontAwesome(18), _
xui.Color_Blue)
El título se crea como CustomMenuItem deshabilitado y no cierra el menú.
Título con imagen
PasteMenu.AddTitleWithImage( _
"Paste Options", _
xui.Color_DarkGray, _
File.DirAssets, _
"paste.png")
CheckMenuItem
PasteMenu.AddCheckItem( _
"KeepFormatting", _
"Keep original formatting", _
Chr(0xF058), _
fx.CreateFontAwesome(18), _
xui.Color_RGB(40, 150, 90), _
True)
Evento real:
Private Sub KeepFormatting_Changed(IsSelected As Boolean)
Log(IsSelected)
End Sub
CheckMenuItem usa EventName_Changed(Boolean), no _Click.
RadioMenuItem
Dim PasteModeGroup As Object = PasteMenu.CreateToggleGroup
PasteMenu.AddRadioItem( _
"NormalPaste", _
"Normal paste", _
"", Null, 0, _
PasteModeGroup, _
True)
PasteMenu.AddRadioItem( _
"TextOnly", _
"Paste text only", _
"", Null, 0, _
PasteModeGroup, _
False)
Evento:
Private Sub NormalPaste_Selected(IsSelected As Boolean)
End Sub
_Selected solo se llama cuando el RadioMenuItem queda seleccionado.
Submenús
Crear
Dim PasteAsMenu As JavaObject
PasteAsMenu = PasteMenu.AddSubMenu( _
"PasteAs", _
"Paste as", _
Chr(0xF0C5), _
fx.CreateFontAwesome(18), _
xui.Color_RGB(60, 120, 220))
Devuelve un JavaObject que representa el Menu JavaFX.
Item de submenú
PasteMenu.AddItemToSubMenu( _
PasteAsMenu, _
"PasteAsText", _
"Text", _
Chr(0xF031), _
fx.CreateFontAwesome(18), _
xui.Color_Blue)
Item con imagen
PasteMenu.AddItemImageToSubMenu( _
PasteAsMenu, _
"PasteAsPicture", _
"Picture", _
File.DirAssets, _
"image.png")
Check
PasteMenu.AddCheckItemToSubMenu( _
PasteAsMenu, _
"MergeLines", _
"Merge lines", _
"", Null, 0, False)
Evento: MergeLines_Changed(IsSelected As Boolean).
Radio
Dim TextMode As Object = PasteMenu.CreateToggleGroup
PasteMenu.AddRadioItemToSubMenu( _
PasteAsMenu, _
"PlainText", _
"Plain text", _
"", Null, 0, _
TextMode, _
True)
Separador
PasteMenu.AddSeparatorToSubMenu(PasteAsMenu)
Título
PasteMenu.AddTitleToSubMenu( _
PasteAsMenu, _
"Text formats", _
xui.Color_DarkGray, _
Chr(0xF031), _
fx.CreateFontAwesome(18), _
xui.Color_Blue)
Título con imagen
PasteMenu.AddTitleWithImageToSubMenu( _
PasteAsMenu, _
"Picture formats", _
xui.Color_DarkGray, _
File.DirAssets, _
"image.png", _
18)
Paneles personalizados en menús
Menú principal
Dim OptionsPanel As B4XView = xui.CreatePanel("")
OptionsPanel.SetLayoutAnimated(0, 0, 0, 240dip, 100dip)
PasteMenu.AddCustomPanel(OptionsPanel, False)
HideOnClick controla si el popup se cierra al hacer clic en el panel.
Submenú
PasteMenu.AddCustomPanelToSubMenu(PasteAsMenu, OptionsPanel, False)
Esto permite colocar sliders, previews, paletas de color u otras vistas dentro del popup.
Limpiar menús
PasteMenu.Clear
PasteMenu.ClearSubMenu(PasteAsMenu)
Es útil para reconstruir menús dinámicos según el estado de la aplicación.
Quick Access Bar
Ribbon mantiene zona izquierda y derecha.
Izquierda con imagen
Ribbon1.AddQuickAccessButtonImage( _
"save", _
File.DirAssets, _
"save.png", _
"Save")
Izquierda con icono
Ribbon1.AddQuickAccessButtonIcon( _
"undo", _
fx.CreateFontAwesome(18), _
Chr(0xF0E2), _
xui.Color_RGB(55, 80, 190), _
"Undo")
Derecha con imagen
Ribbon1.AddQuickAccessButtonRightImage( _
"help", _
File.DirAssets, _
"help.png", _
"Help")
Derecha con icono
Ribbon1.AddQuickAccessButtonRightIcon( _
"info", _
fx.CreateFontAwesome(18), _
Chr(0xF05A), _
xui.Color_RGB(60, 130, 230), _
"Information")
Todos usan eventos directos:
Private Sub save_Click
End Sub
Obtener botón
Dim B As Button = Ribbon1.GetButtonQuickBar("save")
Nota de implementación
Los botones se guardan en un Map con el EventName original, mientras GetButtonQuickBar convierte el texto consultado a minúsculas. Para evitar diferencias de mayúsculas/minúsculas, usa EventName en minúsculas si luego necesitas recuperarlo con GetButtonQuickBar.
QuickAccessBar nativo
Dim NativeQuick As JavaObject = Ribbon1.GetCurrentQuickAccessBar
Si no existe, se crea un com.pixelduke.control.ribbon.QuickAccessBar.
Limpiar Quick Access
Ribbon1.RemoveAllQuickAccessButtons
RibbonQuickAccess — API avanzada
Dim QA As RibbonQuickAccess
QA.Initialize(Ribbon1.GetCurrentQuickAccessBar)
If QA.IsReady Then
Log("QuickAccess listo")
End If
Crear un Button JavaFX nativo:
Dim NativeButton As JavaObject = QA.CreateNativeButton("")
Agregar un Button B4J:
Dim MyButton As Button
MyButton.Initialize("MyQuick")
MyButton.Text = "Q"
QA.AddButton(MyButton)
Derecha:
QA.AddRightButton(MyButton)
JavaObject:
Dim QuickJO As JavaObject = QA.AsJO
Para uso normal son preferibles los métodos AddQuickAccessButton... de Ribbon.
Agregar y quitar tabs
Ribbon1.AddTab(MyTab)
Ribbon1.RemoveTab(MyTab)
Ribbon1.RemoveAllTabs
Ribbon mantiene una lista interna de tabs para fuentes y estilos.
Temas y AddThemesTap
Cambiar tema:
Ribbon1.Theme = "Modern"
Temas soportados:
Office2007
Office2019
Office2021
Modern
FluentFusion
NeonTheme
FluentDesing
FlatRibbon
GlassMinimal
MidnightGlass
NordicLight
Aurora
Helper:
Ribbon1.AddThemesTap(ThemesTab, "Themes")
El nombre del método en el código es AddThemesTap.
Comportamiento actual del helper
Aunque Theme soporta 12 temas, AddThemesTap crea botones para los primeros 8:
Office2007
Office2019
Office2021
Modern
FluentFusion
FluentDesing
NeonTheme
FlatRibbon
Los handlers theme9_Click a theme12_Click existen para GlassMinimal, MidnightGlass, NordicLight y Aurora, pero el helper actual no crea esos cuatro botones automáticamente.
Puedes agregarlos manualmente y cambiar Theme desde sus eventos.
Ejemplo completo
Private Sub BuildApplicationRibbon
Dim SmallFont As B4XFont = fx.CreateFontAwesome(18)
Ribbon1.AddQuickAccessButtonIcon( _
"save", SmallFont, Chr(0xF0C7), _
xui.Color_RGB(30, 100, 210), "Save")
Ribbon1.AddQuickAccessButtonIcon( _
"undo", SmallFont, Chr(0xF0E2), _
xui.Color_RGB(60, 80, 190), "Undo")
Dim HomeTab As RibbonTab
HomeTab.Initialize(Me, "HomeTab", "Home")
Dim FileGroup As RibbonGroup
FileGroup.Initialize(Me, "File")
FileGroup.AddButtonImage( _
"NewFile", File.DirAssets, "new.png", _
"New File", "Create a new file")
FileGroup.AddButtonImage( _
"OpenFile", File.DirAssets, "open.png", _
"Open File", "Open an existing file")
HomeTab.addGroup(FileGroup)
Dim ClipboardGroup As RibbonGroup
ClipboardGroup.Initialize(Me, "Clipboard")
Dim Compact As RibbonButtonGroup
Compact.Initialize(Me, "ClipboardButtons")
Compact.AddButtonIcon( _
"Cut", SmallFont, Chr(0xF0C4), _
fx.Colors.Blue, "Cut", "Cut")
Compact.AddButtonIcon( _
"Copy", SmallFont, Chr(0xF0C5), _
fx.Colors.Gray, "Copy", "Copy")
ClipboardGroup.addButtonGroup(Compact)
Dim PasteMenu As RibbonMenu
PasteMenu.Initialize(Me, "PasteMenu")
PasteMenu.InitializeGroup("Paste")
PasteMenu.CreateWithImage(File.DirAssets, "paste.png", "Paste options")
PasteMenu.AddItem("PastePlain", "Paste plain text")
PasteMenu.AddItem("PasteFormatted", "Paste with formatting")
PasteMenu.AddSeparator
PasteMenu.AddCheckItem("KeepFormatting", "Keep original formatting", "", Null, 0, True)
Dim SubOptions As JavaObject
SubOptions = PasteMenu.AddSubMenu("PasteOptions", "Options", "", Null, 0)
PasteMenu.AddItemToSubMenu(SubOptions, "NormalPaste", "Normal paste", "", Null, 0)
PasteMenu.AddItemToSubMenu(SubOptions, "TextOnly", "Paste text only", "", Null, 0)
ClipboardGroup.AddRibbonMenu(PasteMenu)
HomeTab.addGroup(ClipboardGroup)
Ribbon1.AddTab(HomeTab)
End Sub
Private Sub save_Click
End Sub
Private Sub undo_Click
End Sub
Private Sub NewFile_Click
End Sub
Private Sub OpenFile_Click
End Sub
Private Sub Cut_Click
End Sub
Private Sub Copy_Click
End Sub
Private Sub PastePlain_Click
End Sub
Private Sub PasteFormatted_Click
End Sub
Private Sub KeepFormatting_Changed(IsSelected As Boolean)
End Sub
Private Sub NormalPaste_Click
End Sub
Private Sub TextOnly_Click
End Sub
Private Sub Ribbon1_TabChanged(Index As Int, TabName As String)
Log(Index & " - " & TabName)
End Sub
GradientPanel — complemento opcional
GradientPanel está agrupado con Ribbon UI en el proyecto, pero Ribbon no lo usa como dependencia obligatoria.
Dim Colors As List
Colors.Initialize
Colors.Add("#17365D")
Colors.Add("#2F75B5")
Dim GP As GradientPanel
GP.Initialize(MyPane, Colors, "TL_BR", 0)
Actualizar:
GP.UpdateColors(NewColors)
GP.UpdateBlurRadius(8)
API pública completa
Ribbon
| API | Función |
|---|---|
| Initialize | Inicializa |
| DesignerCreateView | Custom View |
| AddQuickAccessButtonImage | Quick Access izquierdo con imagen |
| AddQuickAccessButtonRightImage | Quick Access derecho con imagen |
| AddQuickAccessButtonIcon | Quick Access izquierdo con icono |
| AddQuickAccessButtonRightIcon | Quick Access derecho con icono |
| GetButtonQuickBar | Recupera Button |
| GetCurrentQuickAccessBar | QuickAccessBar Java |
| GetBase | Pane base |
| RemoveAllTabs | Borra tabs |
| RemoveAllQuickAccessButtons | Borra Quick Access |
| RemoveTab | Borra un tab |
| AsJO | JavaObject |
| AsNode | Node |
| AddTab | Agrega tab |
| AddThemesTap | Crea grupo/tab de temas |
| UpdateAllRibbonFonts | Actualiza fuentes |
| Theme | Establece tema |
| ColorGroup | Fondo de grupos |
| TitleGroupColor | Texto de grupo |
| ColorLabelControls | Texto de controles |
| SelectColor | Accent |
| TitleTapColor | Texto de tabs |
| SeparatorColor | Separadores |
| CurrentTheme | Tema actual |
RibbonTab
| API | Función |
|---|---|
| Initialize | Crea tab |
| SetTabImage | Imagen |
| SetTabIcon | Icono de fuente |
| GetBase | Pane |
| SetDefaultUserAgentStylesheet | Inicializa CSS nativo |
| SplitPane | SplitPane interno |
| AsJO | JavaObject |
| AsNode | Node |
| addGroup | Agrega grupo |
| BackgroundColor | Fondo |
| IsMenuButton | Detecta MenuButton |
| GetGroupsList | Lista de grupos |
| UpdateAllRibbonFonts | Actualiza fuentes |
| UpdateAllRibbonFonts3 | Variante de actualización |
RibbonGroup
| API | Función |
|---|---|
| Initialize | Crea grupo |
| DesignerCreateView | Soporte Designer |
| AddToParent | Crea base manual |
| GetBase | Pane |
| SetDefaultUserAgentStylesheet | CSS nativo |
| NodeCount | Cantidad de nodos |
| SplitPane | SplitPane |
| SetGroupIcon | Icono de título |
| SetGroupImage | Imagen de título |
| AsJO | JavaObject |
| AsNode | Node |
| addView | Agrega vista |
| AddButtonImage | Botón grande imagen |
| AddButtonIcon | Botón grande icono |
| addTitle | Título |
| TitlesColor | Color título |
| ColorLabelcontrol | Color labels |
| BackgroundColor | Fondo |
| addButtonGroup | RibbonButtonGroup |
| UpdateButtonGroupFonts | Fuentes |
| addSmartButtonGroup | RibbonSmartButtonGroup |
| AddRibbonMenu | RibbonMenu |
| GetButton | Recupera Button |
| SetButtonVisible | Visible |
| SetButtonEnabled | Enabled |
| font | Fuente pública |
RibbonButtonGroup
| API | Función |
|---|---|
| Initialize | Inicializa |
| DesignerCreateView | Designer |
| GetBase | B4XView |
| UpdateFont | Fuente |
| AddButtonImage | Botón compacto imagen + texto |
| AddButtonIcon | Botón compacto icono + texto |
| GetButton | Recupera Button |
| SetButtonEnabled | Enabled |
| AddRibbonMenu | Menú compacto |
| font | Fuente |
RibbonSmartButtonGroup
| API | Función |
|---|---|
| Initialize | Inicializa |
| AddRibbonMenu | Menú compacto |
| DesignerCreateView | Designer |
| GetBase | B4XView |
| AddButtonImage | Botón imagen |
| AddButtonIcon | Botón icono |
| GetButton | Recupera Button |
| SetButtonEnabled | Enabled |
| font | Fuente |
RibbonMenu
| API | Función |
|---|---|
| Initialize | Inicializa callback |
| InitializeGroup | Modo grande |
| InitializeButtonGroup | Modo compacto |
| InitializeSmartButtonGroup | Modo smart |
| CreateWithIcon | Crea control con icono |
| CreateWithImage | Crea control con imagen |
| AddItem | Item |
| AddItemImage | Item con imagen |
| GetNode | Node principal |
| AddSeparator | Separador |
| AddTitle | Título |
| AddTitleWithImage | Título con imagen |
| AddCheckItem | CheckMenuItem |
| AddRadioItem | RadioMenuItem |
| CreateToggleGroup | ToggleGroup |
| AddCustomPanel | Panel personalizado |
| UpdateFont | Fuente |
| AddSubMenu | Submenu |
| AddItemToSubMenu | Item de submenu |
| AddItemImageToSubMenu | Item con imagen |
| AddCheckItemToSubMenu | Check |
| AddRadioItemToSubMenu | Radio |
| AddSeparatorToSubMenu | Separador |
| AddTitleToSubMenu | Título |
| AddTitleWithImageToSubMenu | Título con imagen |
| AddCustomPanelToSubMenu | Panel personalizado |
| ClearSubMenu | Limpia submenu |
| Clear | Limpia menú |
| Tag | Dato público |
| font | Fuente |
| IsButtonGroup | Estado público |
RibbonQuickAccess
| API | Función |
|---|---|
| Initialize | Envuelve QuickAccessBar |
| CreateNativeButton | Crea Button Java |
| AddButton | Agrega izquierda |
| AddRightButton | Agrega derecha |
| AsJO | JavaObject |
| IsReady | Estado |
GradientPanel
| API | Función |
|---|---|
| Initialize(TargetPane, Colors, Orientation, BlurRadius) | Crea gradiente |
| UpdateColors | Cambia colores |
| UpdateBlurRadius | Cambia blur |
Reglas prácticas
- Usa Ribbon principal desde el Designer.
- Construye tabs y grupos desde código.
- Usa RibbonGroup para acciones principales.
- Usa RibbonButtonGroup para icono + texto compacto en tres filas.
- Usa RibbonSmartButtonGroup para iconos pequeños.
- Usa RibbonMenu para dropdowns, checks, radios, submenús y contenido personalizado.
- Usa EventName descriptivos: cada uno genera su propia Sub.
- Usa SetButtonEnabled y SetButtonVisible según el estado del documento.
- Usa Quick Access para acciones globales que deben seguir visibles al cambiar de tab.
- Usa Theme y los setters de color para adaptar el Ribbon al diseño de la aplicación.
- No confundas el Ribbon con toda la ventana: editor, tabla, PDF, status bar y window chrome son responsabilidad de la app.
- En aplicaciones grandes, diseña primero la jerarquía Tab → Group → Control y después aplica tema, colores y fuentes.