Aquí hay una pequeña demo del componente TextHTML en acción. Incluido el uso de LINKS en los textos de una aplicación JavaFX. También pueden ver AQUI una demo Java Web Start.
La biblioteca memeFX está AQUI
Mostrando entradas con la etiqueta text. Mostrar todas las entradas
Mostrando entradas con la etiqueta text. Mostrar todas las entradas
viernes, 24 de abril de 2009
lunes, 20 de abril de 2009
HTML en JavaFX
Componente TextHTML
Ya está disponible el componente TextHTML en la biblioteca memeFX.
Este control -aunque básico- permite incluir contenido mucho mas rico que el permitido por el componente Text, standard en JavaFX.
Por ahora, básicamente permite cambiar los fonts (fuentes), color del texto, la alineación de parrafos, agregar LIKS (enlaces) e incluir algunos caracteres especiales (< > € etc). Para más información visita el sitio del proyecto y mira la documentación.

En el futuro espero incluir imágenes y algun tipo de control sobre ellas (alineación de las imágenes, eventos como mouseOver, etc).
HTML en ImagesAccordion
El componente ImagesAccordion ahora incluye el componente TextHTML para las descripciones extensas de las imágenes.
CLICK AQUI para lanzar un demo Java Web Start

http://code.google.com/p/memefx/
Ya está disponible el componente TextHTML en la biblioteca memeFX.
Este control -aunque básico- permite incluir contenido mucho mas rico que el permitido por el componente Text, standard en JavaFX.
Por ahora, básicamente permite cambiar los fonts (fuentes), color del texto, la alineación de parrafos, agregar LIKS (enlaces) e incluir algunos caracteres especiales (< > € etc). Para más información visita el sitio del proyecto y mira la documentación.

TextHTML {
x: 20, y: 20, wrappingWidth:300
content:
"<p align=justify><font size=24 color=#ffff00>"
"Easter Island</font> <i>(Rapa Nui)</i> is a "
"Polynesian island in the southeastern <font "
"size=24 face=Verdana color=#ff5555>Pacific "
"Ocean</font>. The island is a <font face="
"TimesRoman size=24 color=#55ffff><a href="
"algo>special</a> <i>territory</i></font> of "
"<a href=Chile>Chile</a>. Easter Island is "
"famous for its monumental statues, called "
"<font color=#00ff00 size=18>moai.</font></p>"
onLinkPressed: function(link) { println(link) }
};
En el futuro espero incluir imágenes y algun tipo de control sobre ellas (alineación de las imágenes, eventos como mouseOver, etc).
HTML en ImagesAccordion
El componente ImagesAccordion ahora incluye el componente TextHTML para las descripciones extensas de las imágenes.
CLICK AQUI para lanzar un demo Java Web Start

http://code.google.com/p/memefx/
lunes, 16 de febrero de 2009
Como reemplazar y centrar textos incrustados en archivos Adobe Illustrator con JavaFX
Uno de los beneficios de crear gráfica para JavaFX con Adobe Illustrator, es que luego esta puede ser reemplazada sin necesidad de alterar el código. Esto permite cambiar rápidamente la apariencia de una aplicación o dotarla de "pieles" o "skins" (distintas apariencias, a elección del usuario). Estas plantillas, que permiten incluso cambiar la posición de los elementos en la interfaz de usuario, entre otras cosas, pueden contener textos, que son posibles de reemplazar (haciendo su contenido dinámico).
Pero, para hacerlo hay un par de detalles que es necesario conocer.
Primero crearé una plantilla con Adobe Illustrator:
Una vez generado el archivo .FXZ podemos analizar el código.
Sólo me concentraré en la manipulación de textos, ya que en artículos anteriores he mostrado como trabajar con otro tipo de elementos gráficos generados con Adobe Illustrator.
Primero, crearemos una clase que cargue el archivo gráfico (.fxz) y que obtenga de él los nodos con los objetos.
Revisemos el código:
Esa línea indica desde donde debe descargar el archivo con la gráfica: {__DIR__} apunta al mismo directorio que la aplicación;
Declara algunas variables para contener otros elementos gráficos;
Declara una variable (dispvalue) de tipo TEXTO, para obtener el nodo que contiene el texto que vamos a reemplazar en este ejercicio, y dos variables adicionales asociadas a ese texto: una (dispvaluew) que contendrá el ancho del area reservada originalmente para el texto y otra (dispvaluex) que contendrá la posición horizontal original para el área de texto;
Para rescatar los nodos desde el archivo .fxz, utilizamos los nombres de asignamos a los elementos en el diseño. En nuestro ejemplo, llamamos al elemento de texto que deseamos manipular "jfx:dispvalue" (la identificacion jfx: permite identificar las etiquetas de nodos que importará JavaFX), y por lo tanto, obtenemos ese nodo con un getNode("dispvalue"), e inmediatamente lo convertimos en un Text (as Text).
Ahora bien, uno de los inconvenientes de la modificación de los textos desde un script, es que al modificar el contenido, se modifica el ancho del elemento que contiene el texto, y dependiendo de la alineación también puede modificarse la posición horizontal.
Por eso, al obtener el nodo de texto original, también almaceno la posición (dispvaluex) y el ancho (dispvaluew) que tenía el texto en el diseño. Con esta información más la nueva información de ancho generada al modificar el contenido del texto, puedo calcular la posición centrada del texto.
Para conseguirlo, puedo hacer algo como esto:
Al modificarse degree, obtiene su valor entero y lo convierte en un string. Esto lo hace al incluir la variable como parte de una cadena de texto entre paréntesis de llave... "{expresión}"
A continuación, obtiene el nuevo ancho del texto modificado, con un: elemento_texto.boundsInLocal.width
Finalmente, obtiene la nueva posición horizontal del texto, usando la posición original del texto en el diseño mas la mitad del ancho del texto original. En este punto sabemos cual era el punto medio del texto original (posición respecto a la cual centraremos el nuevo texto).
A esa posición, restamos la mitad del nuevo ancho del texto.... y como resultado, el texto se mantiene visualmente centrado.
La inconveniente con el uso de TextAlignment.CENTER, es que el texto se centra respecto a las demás líneas de un párrafo (con más de una línea), entonces, si usamos un texto con una sóla línea, TextAligment.CENTER no tiene ningún efecto.
En resumen, hay que recuperar el nodo del texto por su nombre, convertilo y almacenarlo como Text, obtener el ancho y posición original del texto en el diseño... y calcular la posición horizontal del texto al modificar su contenido.
Por cierto, es posible exportar los archivos Illustrator a .fxz sin los fonts, pero si te quieres asegurar que los textos se mantendrán en apariencia, tamaño y posición, es mejor incluirlos. El resultado no es extremadamente grande, un font típico pesa cerca de 50KB.
Ojalá esto sea de utilidad.
Pero, para hacerlo hay un par de detalles que es necesario conocer.
Primero crearé una plantilla con Adobe Illustrator:
Una vez generado el archivo .FXZ podemos analizar el código.
Sólo me concentraré en la manipulación de textos, ya que en artículos anteriores he mostrado como trabajar con otro tipo de elementos gráficos generados con Adobe Illustrator.
Primero, crearemos una clase que cargue el archivo gráfico (.fxz) y que obtenga de él los nodos con los objetos.
import javafx.scene.Node;
import javafx.fxd.UiStub;
import javafx.scene.text.*;
public class gaugeui extends UiStub {
override public var url = "{__DIR__}gauge.fxz";
public var reflex: Node;
public var needle: Node;
public var decoration: Node;
public var body: Node;
public var dispvalue: Text;
public-read var dispvaluew;
public-read var dispvaluex;
override protected function update() {
reflex = getNode("reflex");
needle = getNode("needle");
decoration = getNode("decoration");
body = getNode("body");
dispvalue = getNode("dispvalue") as Text;
dispvaluew = dispvalue.boundsInLocal.width;
dispvaluex = dispvalue.boundsInLocal.minX;
}
}
Revisemos el código:
override public var url = "{__DIR__}gauge.fxz";
Esa línea indica desde donde debe descargar el archivo con la gráfica: {__DIR__} apunta al mismo directorio que la aplicación;
public var reflex: Node;
public var needle: Node;
public var decoration: Node;
public var body: Node;
Declara algunas variables para contener otros elementos gráficos;
public var dispvalue: Text;
public-read var dispvaluew;
public-read var dispvaluex;
Declara una variable (dispvalue) de tipo TEXTO, para obtener el nodo que contiene el texto que vamos a reemplazar en este ejercicio, y dos variables adicionales asociadas a ese texto: una (dispvaluew) que contendrá el ancho del area reservada originalmente para el texto y otra (dispvaluex) que contendrá la posición horizontal original para el área de texto;
override protected function update() {
// obtiene los nodos graficos
reflex = getNode("reflex");
needle = getNode("needle");
decoration = getNode("decoration");
body = getNode("body");
// obtiene el nodo, pero lo transforma en texto
dispvalue = getNode("dispvalue") as Text;
// obtiene el ancho del texto original
dispvaluew = dispvalue.boundsInLocal.width;
// obtiene la posicion horizontal original del texto
dispvaluex = dispvalue.boundsInLocal.minX;
}
Para rescatar los nodos desde el archivo .fxz, utilizamos los nombres de asignamos a los elementos en el diseño. En nuestro ejemplo, llamamos al elemento de texto que deseamos manipular "jfx:dispvalue" (la identificacion jfx: permite identificar las etiquetas de nodos que importará JavaFX), y por lo tanto, obtenemos ese nodo con un getNode("dispvalue"), e inmediatamente lo convertimos en un Text (as Text).
Ahora bien, uno de los inconvenientes de la modificación de los textos desde un script, es que al modificar el contenido, se modifica el ancho del elemento que contiene el texto, y dependiendo de la alineación también puede modificarse la posición horizontal.
Por eso, al obtener el nodo de texto original, también almaceno la posición (dispvaluex) y el ancho (dispvaluew) que tenía el texto en el diseño. Con esta información más la nueva información de ancho generada al modificar el contenido del texto, puedo calcular la posición centrada del texto.
Para conseguirlo, puedo hacer algo como esto:
// instancia la clase que carga la gráfica (arriba)
var ui = gaugeui{};
// variable (degree) que mostrará en el area de texto
var degree = 0.0 on replace {
// actualiza contenido con numero entero convertido en string
ui.dispvalue.content="{degree as Integer}";
// obtiene nuevo ancho del texto (alterado por nuevo contenido)
var w = ui.dispvalue.boundsInLocal.width;
// calcula coordenada horizontal para mantener el texto
// centrado respecto a su posicion original en el diseño
ui.dispvalue.x = ui.dispvaluex +
ui.dispvaluew / 2 - w / 2;
};
Al modificarse degree, obtiene su valor entero y lo convierte en un string. Esto lo hace al incluir la variable como parte de una cadena de texto entre paréntesis de llave... "{expresión}"
A continuación, obtiene el nuevo ancho del texto modificado, con un: elemento_texto.boundsInLocal.width
Finalmente, obtiene la nueva posición horizontal del texto, usando la posición original del texto en el diseño mas la mitad del ancho del texto original. En este punto sabemos cual era el punto medio del texto original (posición respecto a la cual centraremos el nuevo texto).
A esa posición, restamos la mitad del nuevo ancho del texto.... y como resultado, el texto se mantiene visualmente centrado.
La inconveniente con el uso de TextAlignment.CENTER, es que el texto se centra respecto a las demás líneas de un párrafo (con más de una línea), entonces, si usamos un texto con una sóla línea, TextAligment.CENTER no tiene ningún efecto.
En resumen, hay que recuperar el nodo del texto por su nombre, convertilo y almacenarlo como Text, obtener el ancho y posición original del texto en el diseño... y calcular la posición horizontal del texto al modificar su contenido.
Por cierto, es posible exportar los archivos Illustrator a .fxz sin los fonts, pero si te quieres asegurar que los textos se mantendrán en apariencia, tamaño y posición, es mejor incluirlos. El resultado no es extremadamente grande, un font típico pesa cerca de 50KB.
Ojalá esto sea de utilidad.
sábado, 17 de enero de 2009
JavaFX: Textos que giran y cambian de tamaño
Este ejercicio lo desarrollé para crear una clase que contiene sus propios timeline y que modifica el tamaño del font mientras gira el mensaje. Quizas lo más interesante de este ejercicio es la manera en que se modifica el tamaño del font desde el timeline. Otra cosa interesante es cómo el programa obtiene las dimensiones del texto para pintar el area que lo contiene (para ello es necesario que el texto sea definido en una variable y luego incluida en el contenido).
package experimenttext;
import javafx.stage.Stage;
import javafx.animation.*;
import javafx.scene.*;
import javafx.scene.text.*;
import javafx.scene.shape.Rectangle;
import javafx.scene.paint.Color;
class myObject extends CustomNode {
// texto en el mensaje
public var message = "Nada aun";
// color del mensaje
public var color = Color.BLACK;
// color borde
public var stroke = Color.BLACK;
// color fondo
public var fill = Color.WHITE;
// tamaño maximo del font
public var max_size = 64.0;
// angulo de la rotacion
var angle: Number;
// tamaño del font
var size: Number;
// font del texto
var varfont = function(size:Number):Font {
Font{
name:"Verdana"
oblique:true;
size:size;
}
};
// mensaje desplegado
var geomText = Text {
content: bind message
font : bind varfont(size)
fill: bind color
textOrigin: TextOrigin.TOP
};
// rotacion del mensaje (un giro en 2 segundos)
var rotatetimeline = Timeline {
repeatCount: Timeline.INDEFINITE
keyFrames: [
at(0s) { angle => 0 }
at(2s) { angle => 360 }
]
};
// variacion del tamaño del font (de 12 a MAX_SIZE en 1 segundos)
var fontsize = Timeline {
repeatCount: Timeline.INDEFINITE
autoReverse: true
keyFrames: [
at(0s) { size => 12 }
at(0.3s) { size => max_size tween Interpolator.EASEBOTH}
]
};
// mensaje desplegado (compuesto por texto y rectangulo a su alrededor)
override protected function create():Node {
// inicia los timelines de la instancia
rotatetimeline.play();
fontsize.play();
Group {
content: [
// rectangulo
Rectangle {
width: bind geomText.boundsInLocal.width
height: bind geomText.boundsInLocal.height
stroke: bind stroke
fill: bind fill
},
// mensaje
geomText
]
// rotacion del conjunto (rect+mensaje)
rotate:bind angle
}
};
};
// primera instancia de mensaje
var msg=myObject{
translateX: 200
translateY: 150
message: "Primer mensaje"
};
// segunda instancia de mensaje
var msg2=myObject{
translateX: 300
translateY: 250
message: "Segundo mensaje"
color: Color.RED
stroke: Color.GREEN
fill: Color.YELLOW
max_size: 40.0
};
// tercera instancia de mensaje
var msg3=myObject{
translateX: 100
translateY: 350
message: "Tercer mensaje"
color: Color.WHITE
stroke: Color.BLUE
fill: Color.BLUE
max_size: 90.0
};
// aplicacion
Stage {
title: "Application title"
width: 800
height: 600
scene: Scene {
content: [
msg,
msg2,
msg3
]
}
}
Suscribirse a:
Entradas (Atom)