Mostrando entradas con la etiqueta cambio. Mostrar todas las entradas
Mostrando entradas con la etiqueta cambio. Mostrar todas las entradas

viernes, 28 de agosto de 2009

Migrando a JavaFX 1.2: de UiStub --> FXDNode


Ayer retomé JavaFX para migrar el proyecto memeFX (código abierto) a la versión JavaFX 1.2 y este es básicamente el único inconveniente que encontré (además de un bug algo extraño que tengo que verificar).

Estas clases se utilizan para obtener recursos gráficos para la aplicación, como las imágenes generadas con Adobe Illustrator:

En JavaFX 1.1 se usaba UiStub del paquete javafx.fxd.UiStub:


import javafx.fxd.UiStub;

public class myClass extends UiStub {

override protected function update() {
...
}

}

Ahora, es necesario utilizar FXDNode también en el paquete javafx.fxd. Sólo hay que hacer este cambio:

import javafx.fxd.FXDNode;

public class BasicKnob extends FXDNode {

override protected function contentLoaded() {
...
}

}

domingo, 12 de abril de 2009

"On Replace" no es "On Modify"...


No tengo claro si hay alguna manera de hacer que "on replace" se dispare al modificar una variable de una clase definida por el usuario (supongo que no, porque se llamaría ON MODIFY). Al parecer es necesario recrear el objeto y asignarlo a la variable para que "on replace" detecte el cambio.

Digamos que defino una clase:

public class Data {
public var attrib1:Number=0.0;
public var attrib2:String="";
}

Luego, creo una instancia de la clase:

var data1:Data = Data {
attrib1: 1.2,
attrib2: "Mauricio"
} on replace {
println("{data1.attrib1} {data1.attrib2}");
};
data1.attrib2="Omar";
data1.attrib2="Veronica";

La salida de este ejemplo es:

1.2 Mauricio

Es decir, al asignar "Omar" o "Veronica" a attrib2, el bloque "on replace" de data1 no se dispara.

La única manera (que conozco) de evitar esto es asignar una nueva instancia del objeto a data1:

data1= Data { attrib1:data1.attrib1 attrib2:"Omar"};

Quizás haya alguna forma de declarar la variable con algún tipo de binding o algo por el estilo que permita detectar los cambios de variables dentro de una instancia.

Por ahora, vale la pena tener este detalle presente para evitar problemas y pérdidas de tiempo... si uno no lo sabe, puede no ser evidente que esa parte del código no se está ejecutando y hay un bug en el código.

"On Replace" aplicado a secuencias


La clausula "on replace", si está presente al momento de definir una variable, causa que el bloque de código sea ejecutado cada vez que el valor de la variable cambia -- incluyendo la asignación inicial de su valor.

Los parametros opcionales proveen información sobre qué cambió: on replace oldValue [ firstIndex .. lastIndex ] = newElements { ... }

Todos estos parámetros son opcionales, y en la más simple de las formas, ninguno está presente:

var x = 0 on replace { println("x is ahora: {x}") }

El parámetro "oldValue" provee el valor previo de la variable.

var x = 0 on replace oldValue {
println("x was {oldValue} and is now: {x}") }

Los parámetros remanentes son utiles con las secuencias.

var seq = ['A', 'B', 'C', 'D', 'E', 'F']
on replace oldValue[firstIdx .. lastIdx] =
newElements { println(
"reemplazo {oldValue}[{firstIdx}..{lastIdx}]"
" por {newElements} produciendo {seq}")
}
seq[3] = '$';
insert '#' into seq;
delete '$' from seq;
delete seq[2];
seq[1..4] = ['X', 'Y'];
delete seq;

Lo que produce está salida:

replaced [0..-1] by ABCDEF yielding ABCDEF
replaced ABCDEF[3..3] by $ yielding ABC$EF
replaced ABC$EF[6..5] by # yielding ABC$EF#
replaced ABC$EF#[3..3] by yielding ABCEF#
replaced ABCEF#[2..2] by yielding ABEF#
replaced ABEF#[1..4] by XY yielding AXY
replaced AXY[0..2] by yielding

Nota que firstIndex, lastIndex and newElements se refieren únicamente a la porción que la secuencia que cambió.

lunes, 19 de enero de 2009

JavaFX: Limita el tamaño de la ventana (mínimo y máximo) - Bind with inverse


Esta es una variación del ejemplo anterior, que detectaba el tamaño de la ventana para ajustar el contenido (cómo descubrir el tamaño de la ventana). En este caso, fuerza dimensiones mínimas y máximas para la ventana.



Como vimos en el ejemplo anterior, la instrucción 'bind with inverse' permite iniciar el tamaño de la ventana unas ciertas dimensiones (300x300 pixeles), pero luego, las variables 'w' y 'h' reciben las variaciones del tamaño de la ventana, a través del mismo 'bind with inverse'. Esto, sumado a la instrucción 'on replace' (al definir las variables para el tamaño de la ventana), permite gatillar la validación del tamaño de la ventana.... y forzar su tamaño dentro de límites al asignar nuevos valores para las variables 'w' y 'h'.

En otras palabras, las variables 'w' y 'h' se hacen BIDIRECCIONALES... pues al modificar su valor, se afecta el tamaño de la ventana.... y al modificar el tamaño de la ventana, se actualiza los valores de las variables, con las nuevas dimensiones.


package experimentsize;

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.shape.*;
import javafx.scene.paint.*;
import javafx.geometry.Rectangle2D;

// borde horizontal de la ventana
var bh=16.0;
// borde vertical de la ventana (incluye titulo)
var bv=36.0;
// dimension minima de la ventana
var minSize=Rectangle2D{width:200 height:200};
// dimension maxima de la ventana
var maxSize=Rectangle2D{width:500 height:500};

// valida dimensiones de la ventana
function validateSize():Void {
if (w<minSize.width) then w=minSize.width;
if (h<minSize.height) then h=minSize.height;
if (w>maxSize.width) then w=maxSize.width;
if (h>maxSize.height) then h=maxSize.height;
println("ajusto ventana a {w} x {h}");
}

// tamaño inicial de la ventana
var w=300.0 on replace {validateSize()};
var h=300.0 on replace {validateSize()};

Stage {
title: "Ajusta a dimension de ventana"
width: bind w with inverse
height: bind h with inverse
scene: Scene {
content: {
Circle {
translateX: bind (w-bh)/2
translateY: bind (h-bv)/2
radius:bind if (w<h) then
(w-50)/2
else
(h-80)/2
fill:Color.RED
}
}
}
}