7.0 KiB
UI Troubleshooting & Resolução de Estilos (JavaFX CSS)
Este documento registra a investigação da causa raiz de problemas visuais na interface gráfica do CyberCore Signer, em especial a falha de renderização de textos com cor preta (Color.BLACK) via setStyle(), a eliminação definitiva de estilos inline de cor e a transição para o tema claro unificado.
1. O Problema: Texto Renderizado em Preto (#000000) via setStyle
Sintoma
Em diálogos modais como ExitConfirmationDialog, PdfSignDialog e PdfCertificateSignDialog, chamadas como:
subtitle.setStyle("-fx-text-fill: -fx-text-secondary;");
lblDocName.setStyle("-fx-text-fill: -fx-text-primary;");
dragTip.setStyle("-fx-text-fill: -fx-text-secondary;");
resultavam em texto renderizado com a cor preta opaca (#000000), mesmo quando o token -fx-text-secondary já se encontrava definido no arquivo theme.css.
2. Investigação Técnica e Causa Raiz
2.1 Por que setStyle("-fx-text-fill: -fx-text-secondary") renderiza PRETO?
No motor de estilização do JavaFX (com.sun.javafx.css.StyleManager / CssStyleHelper):
- Momento da Avaliação (Timing) de Nós Fora da Árvore da Scene:
Quando um nó (como um
LabelouText) é instanciado no código Java dentro do construtor de um diálogo e recebe.setStyle("-fx-text-fill: -fx-text-secondary;"), ele ainda não foi anexado ao grafo de cena (Scene). - Escopo de Resolução de Lookups Ausente:
Como
-fx-text-secondaryé uma cor pesquisada (looked-up color) definida no seletor.rootda folha de estilo da aplicação, a engine de CSS do JavaFX tenta resolver essa variável subindo a cadeia de nós pais (parent chain) até alcançar.root. Como o nó está solto na memória (sem parent e sem Scene vinculada no instante da chamada), o lookup não encontra nenhuma definição válida. - Mecanismo de Fallback Silencioso do Modena (
Color.BLACK): O analisador do JavaFX não lança exceção ao falhar na resolução de uma cor de lookup em estilo inline. Em vez disso, seu conversor (PaintConverter/ColorConverter) assume o valor padrão de salvaguarda da especificação Modena:Color.BLACK(rgba(0, 0, 0, 1.0)). - Imutabilidade e Prioridade do Estilo Inline:
O estilo inline atribuído via
setStyle(...)possui a especificidade mais alta na hierarquia CSS do JavaFX. O valor pré-resolvido comoColor.BLACKfica gravado diretamente no cache de estilo do nó. Quando a Scene finalmente executa a passagem formal de CSS (applyCss()/layout()), a engine prioriza o estilo inline e não reavalia o lookup que falhou previamente.
2.2 Por que o problema não ocorre com Classes CSS?
Quando utilizamos classes semânticas declaradas em folha de estilo (ex.: lbl.getStyleClass().add("text-muted");):
.text-muted {
-fx-text-fill: -fx-text-secondary;
}
A resolução da regra é postergada até que o nó pertença à hierarquia da Scene e a passagem de CSS do JavaFX seja executada. Nesse momento, o nó tem acesso direto às definições de .root, resolvendo perfeitamente o token para a cor correta da paleta (#475569).
3. Diretriz Arquitetural: Proibição de Cores em setStyle()
Fica estabelecido como regra obrigatória de desenvolvimento no cybercore-ui:
-
setStyle()restrito exclusivamente à Geometria:- Permitido: dimensões dinâmicas, larguras mínimas, alturas, alinhamentos e paddings específicos de cálculo em tempo de execução (
-fx-min-width,-fx-pref-width,-fx-padding,-fx-alignment). - Terminantemente proibido em
setStyle():-fx-text-fill-fx-background-color-fx-border-color-fx-fill/-fx-stroke- Códigos hexadecimais (
#...) ou funções cromáticas (rgb(...),rgba(...)) - Nomes de lookups de cor (
-fx-accent,-fx-color-*, etc.)
- Permitido: dimensões dinâmicas, larguras mínimas, alturas, alinhamentos e paddings específicos de cálculo em tempo de execução (
-
Uso Obrigatório de Classes CSS Semânticas:
Classe CSS Finalidade Propriedade Aplicada .text-primaryTexto principal -fx-text-fill: -fx-text-primary;.text-secondary,.text-mutedTexto auxiliar / metadados -fx-text-fill: -fx-text-secondary;.text-accentDestaque primário -fx-text-fill: -fx-accent;.text-boldTipografia em negrito -fx-font-weight: bold;.text-smallTexto compacto -fx-font-size: 11px;.text-monoFonte monoespaçada para hashes -fx-font-family: monospace;.surface-boxContainer de superfície branca com borda -fx-background-color: -fx-color-surface;.toolbar-boxBarra de ferramentas compacta -fx-background-color: -fx-color-surface;.scroll-transparentScrollPane sem fundo cinza -fx-background-color: transparent;.status-ok/.status-warn/.status-errorIndicadores de status Cores semânticas da paleta
4. Salvaguardas Automatizadas
O teste de arquitetura DesignTokenGuardrailTest.java atua como barreira de compilação contínua:
- Varre todos os arquivos
.javano módulocybercore-uie reprova automaticamente o build se qualquer chamadasetStyle()contiver propriedades ou valores de cor. - Valida matematicamente a relação de contraste WCAG AA (mínimo de 4.5:1 para texto normal) em todas as combinações de tokens de texto sobre superfície/fundo.
- Assegura ausência de seletores ou classes residuais de temas escuros (
.theme-dark,AppTheme,isDark()).
5. Comportamento da Barra de Título Nativa no Windows (DWM em Modo Escuro)
Diagnóstico Operacional
Quando o sistema operacional Windows 10/11 está configurado no "Modo Escuro do Sistema" (Personalização > Cores > Escolher o modo: Escuro), o gerenciador de janelas do sistema operacional (Desktop Window Manager — DWM) aplica automaticamente o atributo DWMWA_USE_IMMERSIVE_DARK_MODE na moldura não-cliente da janela nativa (HWND).
Como o CyberCore Signer utiliza decoração nativa padrão (StageStyle.DECORATED) para preservar o comportamento esperado pelo usuário empresarial — incluindo cantos arredondados, atalhos de teclado nativos, suporte a múltiplos monitores com DPIs distintos e os Snap Layouts do Windows 11 — a barra de título nativa é desenhada pelo Windows em tom escuro, enquanto o conteúdo da janela exibe o tema claro unificado da aplicação.
Diretriz de Arquitetura (Não Forçar)
Em estrita conformidade com as diretrizes do projeto (Regras 2 e 23):
- Não forçar a barra de título: Evita-se o uso de hacks de baixo nível via JNA/JNI para sobrescrever o DWM do Windows ou janelas não decoradas (
UNDECORATED), o que causaria quebra de acessibilidade e perda de recursos nativos do sistema. - Harmonia Visual: A moldura do Windows atua como moldura de sistema e o conteúdo claro do CyberCore Signer permanece legível, íntegro e em total conformidade com a especificação de interface.