Mostrando entradas con la etiqueta on replace. Mostrar todas las entradas
Mostrando entradas con la etiqueta on replace. Mostrar todas las entradas

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, 8 de diciembre de 2008

JavaFX: Circulo arrastrable que cambia de color


Este ejemplo dibuja un circulo de radio "rad=60", que cambia de color y que puede ser arrastrado con el mouse. Además, incluye una función que se "dispara" al cambiar el color del círculo (color=0 on replace oldColor {})




package javafxclasses;

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.text.*;
import javafx.scene.input.*;
import javafx.scene.shape.Circle;
import javafx.scene.transform.Transform;

def rad=60.0;
var x1=rad;
var y1=rad;
var dx:Number;
var dy:Number;

var colors = [Color.RED, Color.BLUE, Color.GREEN, Color.YELLOW];

var color=0 on replace oldColor {
println("\nALERT! El color cambio!");
println("Antiguo color: {oldColor}");
println("Nuevo color: {color}");
}

Stage {
title: "Application title"
width: 400
height: 400

scene: Scene {
content: [

Circle {

centerX: bind x1;
centerY: bind y1;
radius: rad
fill: bind colors[color]

onMousePressed: function(e) {

// obtiene distancia entre el centro del círculo
// arrastrado y la posición del mouse al hacer click
dx = x1 - e.x;
dy = y1 - e.y;

if (++color==sizeof colors)
color=0;
}

onMouseDragged : function(e) {
// calcula el centro del círculo aplicando la
// diferencia respecto al centro del círculo al
// comenzar a arrastrarlo
x1 = e.x + dx;
y1 = e.y + dy;
}

}

]

}

}