8 Estilos¶
Introducción¶
Al igual que en Java Swing y en Java AWT se puede aplicar estilos a los componentes a través de las propiedades de estilo. Sin embargo, está no es la forma recomendada de hacerle en JavaFX, ya que se dispone de una forma más familiar de hacerlo y de una forma más sencilla.
JavaFX es compatible con CSS por lo que le podemos aplicar estilos CSS de la siguientes forma:
- A través de un fichero con extensión
css
. - A través de una etiqueta
style
dentro del fichero FXML. - A través del método
setStyle
de los componentes.
Propiedades CSS¶
Los estilos CSS se aplican a los nodos en el scene JavaFX de una manera similar a la forma en que se aplican los estilos CSS a los elementos en HTML DOM. Los estilos se aplican primero al padre y luego a sus hijos. El código está escrito de manera que solo se visiten aquellas ramas del gráfico de escena que podrían necesitar que se vuelva a aplicar CSS. A un nodo se le aplica estilo después de agregarlo al scene. Los estilos se vuelven a aplicar cuando hay un cambio en el estado de pseudoclase, clase de estilo, identificación, estilo en línea o padre del nodo.
Los estilos CSS se aplican de forma asíncrona, es decir, los estilos CSS se cargan y los valores se convierten y se asignan algún tiempo después de que se haya creado y agregado un elemento al scene, pero antes de que el scene se diseñe y pinte por primera vez. Además, si los estilos que se aplican a un objeto han cambiado (por ejemplo, porque su pseudoclase ha cambiado), los valores de los estilos recién aplicados no se aplicarán inmediatamente. En cambio, se aplicarán en algún momento después de que el estado del objeto haya cambiado, pero antes de que se pinte el scene a continuación. Es posible que un estilo se aplique a una variable en un objeto JavaFX al que un programa JavaFX le haya asignado un valor. Dado que los estilos CSS se aplican de forma asíncrona, es posible que un programa asigne valores y los utilice durante algún tiempo antes de que CSS los sobrescriba en un momento arbitrario posterior.
Cada nodo en el scene tiene una variable styleClass
, una lista de cadenas. Esto es análogo al atributo class="..."
que puede aparecer en elementos HTML. Proporcionar una cadena para la variable styleClass
de un nodo hace que las propiedades de estilo de esa clase de estilo se apliquen a este nodo. Los estilos para las clases de estilo se pueden especificar utilizando la sintaxis del selector ".styleClass"
en una hoja de estilos. Tenga en cuenta que un nodo puede tener más de una clase de estilo.
Cada nodo en el gráfico de escena tiene una variable de identificación , una cadena. Esto es análogo al atributo id="..."
que puede aparecer en elementos HTML. Proporcionar una cadena para la variable de identificación de un nodo hace que las propiedades de estilo de este nodo se busquen usando esa identificación. Los estilos para identificadores específicos se pueden especificar utilizando la sintaxis del selector "#nodeId"
en una hoja de estilos.
Cada nodo respeta un conjunto de propiedades que dependen de la clase JavaFX del nodo (a diferencia de su clase de estilo). El valor de propiedad que realmente se aplica depende de la precedencia del origen de la regla, como se describe anteriormente, así como de la especificidad del selector de la regla como se describe en CSS 2. En última instancia, una cadena de valor de propiedad se convierte en un valor JavaFX del tipo apropiado y luego se asigna a una variable de instancia del objeto JavaFX.
Los estilos CSS pueden provenir de hojas de estilo o estilos en línea. Las hojas de estilo se cargan desde las URL especificadas en la variable de hojas de estilo del objeto Scene. Si el scene contiene un control, se carga una hoja de estilo de agente de usuario predeterminada. Los estilos en línea se especifican a través de la API setStyle
del Nodo. Los estilos en línea son análogos al atributo style="..."
de un elemento HTML. Los estilos cargados desde las hojas de estilos de una escena tienen prioridad sobre las reglas de la hoja de estilos del agente de usuario. Los estilos en línea tienen prioridad sobre los estilos que se originan en otros lugares. El orden de precedencia de las reglas de estilo se puede modificar usando "!important"
en una declaración de estilo.
A partir de JavaFX 2.1, la clase Parent
tiene una propiedad de hojas de estilo, que permite configurar hojas de estilo en un contenedor. Esto permite que una rama del scene tenga un conjunto distinto de estilos. Cualquier instancia de Parent puede tener hojas de estilo. Un niño tomará sus estilos de sus propios estilos en línea, las hojas de estilo de todos sus antepasados y cualquier hoja de estilo de la escena.
La URL de una hoja de estilo puede ser una URL absoluta o una URL relativa. Si se proporciona una URL relativa, se resuelve con la URL base del ClassLoader
de la clase de aplicación concreta. Si, por ejemplo, hay una clase principal com.example.cool.ui.Main
que extiende la Aplicación, la URL relativa "com/example/cool/resources/styles.css"
se resolvería correctamente. La URL relativa "../resources/styles.css"
no lo sería, ya que la ruta ".."
relativa a la raíz no es una ruta válida. A menudo es más fácil utilizar el ClassLoader
de alguna clase para encontrar el recurso. Por ejemplo, si el archivo "styles.css"
reside en el mismo paquete que Main, el siguiente código le dará la URL correcta: com.example.cool.ui.Main.class.getResource("styles.css").toExternalForm()
Tenga en cuenta que, a partir de JavaFX 2.1, una URL que consta únicamente de una ruta absoluta (sin esquema ni autoridad) se resuelve en relación con la URL base del ClassLoader
de la clase que extiende la Aplicación. En otras palabras, "/com/example/cool/resources/styles.css"
se trata como "com/example/cool/resources/styles.css"
. Esto es consistente con FXML.
La implementación permite a los diseñadores diseñar una aplicación mediante el uso de hojas de estilo para anular los valores de propiedad establecidos en el código. Esto tiene implicaciones para la cascada; En particular, ¿cuándo un estilo de una hoja de estilos anula un valor establecido en el código? La implementación de JavaFX CSS aplica el siguiente orden de precedencia:
- un estilo de una hoja de estilo del usuario tiene menor prioridad que un valor establecido a partir del código
- un valor establecido a partir del código tiene menor prioridad que una hoja de estilo de scene o principal.
- Los estilos en línea tienen la máxima prioridad.
- Las hojas de estilo de una instancia principal se consideran más específicas que los estilos de las hojas de estilo de escena.
Se han establecido convenciones de nomenclatura para derivar nombres de clases de estilo CSS a partir de nombres de clases JavaFX y para derivar nombres de propiedades CSS a partir de nombres de variables JavaFX. Tenga en cuenta que esto es sólo una convención de nomenclatura; no hay conversión automática de nombres. La mayoría de los nombres JavaFX usan "camel case", es decir, nombres de casos mixtos formados a partir de palabras compuestas, donde la letra inicial de cada subpalabra está en mayúscula. La mayoría de los nombres CSS en el mundo HTML están todos en minúsculas, con palabras compuestas separadas por guiones. Por lo tanto, la convención es tomar los nombres de las clases JavaFX y formar su correspondiente nombre de clase de estilo CSS separando las palabras compuestas con guiones y convirtiendo las letras a minúsculas. Por ejemplo, la clase JavaFX ToggleButton
tendría una clase de estilo de "botón de alternancia". La convención para asignar nombres de variables JavaFX a nombres de propiedades CSS es similar, con la adición del prefijo "-fx-". Por ejemplo, la variable blendMode
tendría un nombre de propiedad CSS correspondiente de "-fx-blend-mode".
Si bien el analizador CSS JavaFX analizará la sintaxis CSS válida, no es un analizador CSS totalmente compatible. No se debe esperar que el analizador maneje una sintaxis no especificada en este documento.
- Las declaraciones de palabras clave
@
se ignoran. - Las pseudoclases
":first-child"
y":lang"
no son compatibles. - Los pseudoelementos
":first-line"
,":first-letter"
,":after"
y":before"
no son compatibles. - Las pseudoclases dinámicas
":active"
y":focus"
no son compatibles. Sin embargo, los nodos admiten las pseudoclases":pressed"
y":focused"
, que son similares. - Las pseudoclases
":link"
y":visited"
no son compatibles en general. Sin embargo, a los objetos Hipervínculo se les puede aplicar estilo y admiten la pseudoclase":visited"
. - JavaFX CSS no admite series de nombres de familias de fuentes separadas por comas en la propiedad
-fx-font-family
. - No se admite el parámetro de altura de línea opcional al especificar fuentes.
- No existe ningún equivalente para la propiedad
font-variant
. - JavaFX CSS utiliza el modelo de color
HSB
en lugar del modelo de colorHSL
. - Es posible utilizar el nombre de clase JavaFX como selector de tipo; sin embargo, no se recomienda dicho uso. Por ejemplo, es posible especificar estilos para un
ToggleButton
usando la sintaxis "ToggleButton {...}". No se recomienda este uso porque el nombre utilizado para hacer coincidir el selector de tipo es el nombre de clase concreto real utilizado en el programa JavaFX. Este nombre de clase puede cambiar en el caso de subclases. Si la aplicación subclasificara la claseToggleButton
, estos estilos ya no se aplicarían.
En este momento, las interfaces de programación necesarias para que una clase declare soporte para propiedades CSS, convierta y cargue estos valores de hojas de estilos CSS en variables de objeto y declare y notifique cambios en las pseudoclases de un objeto, se consideran interfaces internas y no son accesibles directamente a las aplicaciones.
Si una propiedad de un nodo se inicializa llamando al método set
de la propiedad, la implementación de CSS verá esto como un valor establecido por el usuario y el valor no será sobrescrito por un estilo de una hoja de estilo de agente de usuario.
CSS también permite que ciertas propiedades se hereden de forma predeterminada, o se hereden si el valor de la propiedad es heredar. Si un valor se hereda, se hereda del valor calculado del elemento principal en el árbol del documento. En JavaFX, la herencia es similar, excepto que en lugar de elementos en el árbol del documento, la herencia ocurre desde los nodos principales en el gráfico de escena.
Info
A través de la siguiente web puedes conocer una lista con el nombre de las propiedades.
https://docs.oracle.com/javafx/2/api/javafx/scene/doc-files/cssref.html#introscenegraph
Haciendo uso del método setStyle
o de la etiqueta style
de FXML se puede añadir estilos:
Clases CSS¶
Para añadir una clase CSS a un elemento de JavaFx se puede utilizar el método add
de la lista styleClass
:
O también desde FXML:
Hojas de estilos¶
Las hojas de estilos CSS puede ser añadidas a la aplicación CSS de varias formas:
-
En el objeto
Scene
a través de su propiedadstylesheets
: -
En el objeto padre del componente a través de la propiedad
styleSheets
: