Archivo

Archivo para la categoría ‘javafx’

¿Como configurar Netbeans 7.10 beta y JavaFX 2.0 beta en OSX?

Sábado, 15 de octubre de 2011

Es un poco fastidioso, pero una vez que se bajen los binarios y siguiendo las instrucciones (no muy precisas de Oracle) terminé haciendo esto:

Netbeans 1.7.1 (beta) + JavaFX 2.0 (beta)

¡Ahora a jugar! :-)

java, javafx

Hackeando mis datos en NikeRunning.com

Miércoles, 12 de octubre de 2011


Tipos de terreno para todas mis carreras, desde NikeRunning, mostrado con JavaFX

Desde que comencé a correr he utilizado a NikeRunning.com de una u otra manera; Primero comencé con mi Itouch y ahora lo utilizó con el NikeWatch.

Sin embargo, el sitio de Nike es un poco fastidioso; El sitio web está escrito en Flash (lo cual lo hace pesado), tiene gráficos limitados pero lo mas inconveniente es que mis datos están cautivos en el sitio web. Según ellos ya llevan tiempo trabajando en una migración que eliminará Flash:

Hello Everyone,

Thank you all for your feedback.

To let everyone know, we are in the process of revamping our website. We are in transition to move away from flash to HTML. The goal is to be faster and more efficient.

We thank you for your patience as we update our sites. There is not an estimated time of when the transition will be fixed, but I can assure you that I’ve seen parts of the site and it’s looks and feels amazing.

Stay tuned!

Buscando un poco en Google me conseguí conque se puede obtener toda la información de las carreras (siempre y cuando estas esten marcadas como públicas) usando el siguiente URL:

1
http://nikerunning.nike.com/nikeplus/v1/services/widget/get_public_run_list.jsp?userID=IDENTIFICADOR_DE_USUARIO

El archivo resultante está en formato XML.

Pero, ¿y de donde obtenemos el identificador del usuario? Es sencillo, simplemente vaya a nikerunning.nike.com y una vez que entre con su usuario y clave al sitio web haga click sobre una de sus corridas. El URL resultante se verá como esto:

1
http://nikerunning.nike.com/nikeos/p/nikeplus/en_US/plus/#//runs/gps/IDENTIFICADOR_DE_USUARIO/299193444/

En donde IDENTIFICADOR_DE_USUARIO es el número mágico que queremos usar.

Se me ocurrió por ejemplo escribir un pequeño programa en Jython y JavaFX el cual muestra la distribución de tipos de terreno encontrados mientras corrí:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/usr/bin/env jython
# Author: Jose Vicente Nunez Zuleta, josevnz@kodegeek.com
# This script parses the user run data and creates a simple distribtion by terrain types
# See: http://nikerunning.nike.com/nikeos/p/nikeplus/en_EMEA/plus/#//dashboard/
# Nike and Nikeplus/Nike+ are trademarks owned by Nike.
# License: BSD
import sys
from javafx.application import Application
from javafx.collections import FXCollections
from javafx.collections import ObservableList
from javafx.scene import Scene
from javafx.stage import Stage
from javafx.scene.chart import PieChart
from javafx.scene import Group
from com.kodegeek.fitness.nikerun.query import CannedQuery
from com.kodegeek.fitness.nikerun.public import PlusPublicService
 
class TerrainTypesChart(Application):
 
    def __getData__(self):
        args = self.getParameters().getRaw()
        pServ = PlusPublicService(args[0])
        data = pServ.getUserData()
        dp = CannedQuery('string', data)
        return dp.getTypesOfTerrain()
 
    def start(self, stage):
        scene = Scene(Group())
        stage.setTitle("Terrain types found in all races")
        stage.setWidth(500)
        stage.setHeight(500)
 
        count = self.__getData__()
        data = [PieChart.Data(key, value) for (key, value) in count.iteritems()]
        pieChartData = FXCollections.observableArrayList(data)
        chart = PieChart(pieChartData)
        chart.setTitle("Terrain types found")
 
        scene.getRoot().getChildren().add(chart)
        stage.setScene(scene)
        stage.show()
 
if __name__ == "__main__":
        Application.launch(TerrainTypesChart().class, sys.argv[1:])

La clase ‘PlusPublicService’ no es más que un simple cliente GET el cual se baja los datos del sitio de Nike:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
!/usr/bin/env jython
#
# Author: Jose Vicente Nunez Zuleta, josevnz@kodegeek.com
# See: http://nikerunning.nike.com/nikeos/p/nikeplus/en_EMEA/plus/#//dashboard/
# Nike and Nikeplus/Nike+ are trademarks owned by Nike.
# License: BSD
#
from httplib import HTTPConnection, HTTP_PORT
import sys
 
__URL__ = 'nikerunning.nike.com'
__SERVICE__ = '/nikeplus/v1/services/widget/get_public_run_list.jsp?userID='
 
class PlusPublicService:
 
        def __init__(self, userId, port = HTTP_PORT):
                self.service = __SERVICE__ + userId
                self.userId = userId
                self.port = port
 
        def getUserData(self, debug=0):
                data = None
                con = HTTPConnection(__URL__, self.port)
                con.set_debuglevel(debug)
                con.request('GET', self.service)
                response = con.getresponse()
                if response.status == 200:
                        data = response.read()
                else:
                        raise Exception("Error. Status = %s, reason = %s" % (response.status, response.reason))
                con.close()
                return data
 
if __name__ == "__main__":
        argv = sys.argv[1:]
        if len(argv) > 0:
                pServ = PlusPublicService(argv[0])
                print "%s" % pServ.getUserData(8)
        else:
                print "NikeRunning user id is required!"
                sys.exit(192)

Y para procesar mis datos utilizo un poco de XPATH en la clase ‘CannedQuery’ la cual tiene un método el cual se encarga de crear la distribución para los distintos tipos de terreno:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/usr/bin/env jython
# Author: Jose Vicente Nunez Zuleta, josevnz@kodegeek.com
# See: http://nikerunning.nike.com/nikeos/p/nikeplus/en_EMEA/plus/#//dashboard/
# Nike and Nikeplus/Nike+ are trademarks owned by Nike.
# License: BSD
 
from xml.dom.minidom import parse, parseString
from xml.etree import ElementTree
import sys
 
class DataParser(object):
 
        def __init__(self, type='string'):
                self.type = type
 
        def __parseDomFile__(self, file):
                return parse(open(file, 'r'))
 
        def __parseDomString__(self, string):
                return parseString(string)
 
        def __parseXpathFile__(self, file):
                return ElementTree.parse(file)
 
        def __parseXpathString__(self, string):
                return ElementTree.fromstring(string)
 
        def __getDom__(self, source):
                if self.type == 'string':
                        return self.__parseDomString__(source)
                else:
                        return self.__parseDomFile__(source)
 
        def __getTree__(self, source):
                if self.type == 'string':
                        return self.__parseXpathString__(source)
                else:
                        return self.__parseXpathFile__(source)
 
class CannedQuery(DataParser):
 
        def __init__(self, type, source):
                super(CannedQuery, self).__init__(type)
                self.source = source
                self.terrainMap = { '0': 'Not defined', '1': 'Road', '2': 'Trail', '3': 'Treadmill', '4': 'Track' }
 
        def getTypesOfTerrain(self):
                tree = self.__getTree__(self.source)
                count = {}
                for elem in tree.findall(".//terrain"):
                        key = 'Never collected'
                        if elem.text in self.terrainMap:
                                key = self.terrainMap[elem.text]
                        if key in count:
                                count[key] += 1
                        else:
                                count[key] = 1
                return count
 
if __name__ == "__main__":
        argv = sys.argv[1:]
        if len(argv) > 0:
                dp = CannedQuery('file', argv[0])
                count = dp.getTypesOfTerrain()
                print "%s" % count

Pienso abrir un proyecto con todas estas clases de Python (Jython) en unos pocos días. Quiero agregarle un par de cosas más antes de soltarlas al aire libre :-)

internet, java, javafx, kodegeek, vida sana

Jython + JavaFX: Comienzo duro

Domingo, 9 de octubre de 2011

Al fin Oracle liberó su versión final de JavFX en JavaOne 2011; También hay una versión beta para OSX la cual me baje de una vez.

Jugando con los ejemplos me dediqué a experimentar con el ejemplo de un gráfico de torta el cual se ve sencillo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.chart.PieChart;
import javafx.scene.Group;
 
public class PieChartSample extends Application {
 
    @Override public void start(Stage stage) {
        Scene scene = new Scene(new Group());
        stage.setTitle("Imported Fruits");
        stage.setWidth(500);
        stage.setHeight(500);
 
        ObservableList pieChartData =
                FXCollections.observableArrayList(
                new PieChart.Data("Grapefruit", 13),
                new PieChart.Data("Oranges", 25),
                new PieChart.Data("Plums", 10),
                new PieChart.Data("Pears", 22),
                new PieChart.Data("Apples", 30));
        final PieChart chart = new PieChart(pieChartData);
        chart.setTitle("Imported Fruits");
 
        ((Group) scene.getRoot()).getChildren().add(chart);
        stage.setScene(scene);
        stage.show();
    }
 
    public static void main(String[] args) {
        launch(args);
    }
}

Lo compilamos y corremos:

1
2
3
Macintosh:javafx josevnz$ export CLASSPATH=/Users/Shared/javafx-sdk2.0.2-beta//rt/lib/jfxrt.jar:.
Macintosh:javafx josevnz$ javac PieChartSample.java -d .
Macintosh:javafx josevnz$ java PieChartSample

JavaFX Pie chartJavaFX gráfico de torta en acción

Así que traté de convertir este sencillo código a Jython:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#!/usr/bin/env jython
import sys
from javafx.application import Application
from javafx.collections import FXCollections
from javafx.collections import ObservableList
from javafx.scene import Scene
from javafx.stage import Stage
from javafx.scene.chart import PieChart
from javafx.scene import Group
 
class PieChartSample(Application):
 
    def __init__(self):
        pass
 
    def start(self, stage):
        scene = Scene(Group())
        stage.setTitle("Imported Fruits")
        stage.setWidth(500)
        stage.setHeight(500)
 
        pieChartData = FXCollections.observableArrayList(
                PieChart.Data("Grapefruit", 13),
                PieChart.Data("Oranges", 25),
                PieChart.Data("Plums", 10),
                PieChart.Data("Pears", 22),
                PieChart.Data("Apples", 30))
        chart = PieChart(pieChartData)
        chart.setTitle("Imported Fruits")
 
        scene.getRoot().getChildren().add(chart)
        stage.setScene(scene)
        stage.show()
 
if __name__ == "__main__":
        PieChartSample().launch(sys.argv[1:])

Pero al correrlo me se queja que no estoy extendiendo bien la clase ‘Aplication’ y por eso falla:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Macintosh:javafx josevnz$ ./piechart.py 
*sys-package-mgr*: can't create package cache dir, '/Users/Shared/jython2.5.2/cachedir/packages'
Traceback (most recent call last):
  File "./piechart.py", line 36, in <module>
    PieChartSample().launch(sys.argv[1:])
	at javafx.application.Application.launch(Application.java:186)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
 
java.lang.RuntimeException: java.lang.RuntimeException: Error: class sun.reflect.NativeMethodAccessorImpl is not a subclass of javafx.application.Application
 
</module>

No tengo ni idea en donde esta el error, ¿alguno de ustedes tiene una pista? De verdad me muero de ganas por usar JavaFX con Jython, ya otros han tenido éxito similar con JRuby y Groovy.

Amanecerá y veremos.

Actualización: De la lista de Jython me llegaron muchas sugerencias, al final Weiqi Gao encontró cual era el verdadero problema y esta es la solución:

1
2
3
# The key to happiness in JavaFX + Jython is this:
if __name__ == "__main__":
    Application.launch(PieChartSample().class, sys.argv[1:])

La explicación detallada a continuación:

The trick is with the last line of code that launches the application, which is accomplished with the javafx.application.Application.launch() method. There are two overloaded versions of this method:

1
public static void launch(String[] args);

and

1
public static void launch(Class< ? extends Application> appClass, String[] args);

The first version must be called from a method in a class that extends Application, which is not the case in the above python code. So we have to use the second version.

The idiom for using the first version of launch() in Java is the following:

1
2
3
4
5
6
7
8
9
10
public class Foo extends Application {
    @Override
    public void start(Stage stage) {
      // build the scene graph and show it
    }
 
    public static void main(String[] args) {
      Application.launch(args); 
    }
}

The idiom for using the second version of launch() in Java is the following:

1
2
3
4
5
6
7
8
9
10
11
12
public class Foo extends Application {
  @Override
  public void start(Stage stage) {
    // build the scene graph and show it
  }
}
 
public class Launcher {
  public static void main(String[] args) {
    Application.launch(Foo.class, args);
  }
}

There is an inefficiency in my python code in that I instantiated PieChartSample once only to get its class. I think there is a better way of doing it but can’t think of how at the moment.

java, javafx, python

Book reviews: JavaFX 1.2 Application Development Cookbook

Miércoles, 17 de noviembre de 2010

JavaFX 1.2 Application Development Cookbook is a really nice book; The cookbook title is a little bit misleading as the book is a quick progression over the features of the language and how it can be used to write applications, all done in a very professional y concise manner.

Then why it is difficult to wrote about this book? Well, the first issue is than the latest API (with significant changes) for JavaFX is 1.3 while the book is written for 1.2; There are several performance and stability improvements, new graphic controls so this was definitely an mandatory upgrade for anyone thinking seriously into using the language. But the real deal breaker here is than JavaFX script is being discontinued and instead is being made a proper Java API that can be used by your regular Java developers.

All this will happen on the ‘JavaFX 2.0′ version of the language, sometime next year. Also JavaFX script is not really dead … is reincarnated as an open source platform called Visage.

So if I were you I would wait to see how JavaFX 2.0 looks like instead, no investment in books or coding for the time being. As for Visage, I would rather go for a head to head comparison with other tools like Apache Pivot which is more mature at this point.

The good: The book is a good one, easy to read and with good concrete examples. The price tag is also good.

The bad: Not a problem with the book itself, but the technology is changing to fast and too much, so it doesn’t make sense to invest on this book. Wait until Oracle delivers JavaFX 2.0.

The ugly: Oracle should have pull the plug sooner. JavaFX has lost a lot of momentum and makes you wonder if now it’s real purpose will be to replace an aging Swing on the desktop.

There are great things scheduled for JavaFX, but we will have to wait some more to see them. Perhaps a new version of this book will be more than welcome once the new version is out.

–Jose

java, javafx, oracle, programación , , , ,

Más fotos del Java Road Trip

Jueves, 26 de agosto de 2010

Bueno, Oracle publicó más fotos del Java road trip en Flickr, del cual les habia hablado ya dos meses atrás en New York. Como pueden ver por cada conjunto, el “Java bus” se ha movido por varias ciudades, incluso tienen un avión :)

No sé, pero yo no he visto el primer RubyBus o C#Bus (Esta bien, está bien sólo estoy bromeando aquí :) )

java, javafx, oracle, programación , , ,

NetBeans 6.9 ya está afuera, JUnit no incluido en JavaFX

Viernes, 18 de junio de 2010

Para quienes han seguido el asunto de NetBeans (el cual ya salió en su versión final 6.9) y la cucaracha de JUnit, este es el resultado: JUnit no es soportado en proyectos de JavaFX.

Uno de los desarrolladores de NetBeans me mostró en el reporte de la cucaracha en donde está desactivado.

¿Entonces, cual es la solución? Bueno, algo inconveniente pero que funciona, simplemente cree un proyecto de Java (no JavaFX) y entonces desde allí incluya sus pruebas de unidad.

Pero como una foto dice más que mil palabras les dejo el ejemplo abajo, creado con uno de los ‘magos de código’ (wizzards) de NetBeans:


¡Misterio resuelto!

java, javafx, opensource, oracle, programación , ,

NetBeans 6.9: JUnit aún está roto

Domingo, 13 de junio de 2010

Después de probar varias soluciones que leí en la red y de ver como aún la versión 6.9 RC2 aún tiene esta cucaracha me decidí a reportar el problema.

La cucaracha es la 187528.

Si tu eres uno de los afectados te invito a comentar esta cucaracha, de esta manera los desarrolladores de NetBeans le darán más prioridad ;)

–José

java, javafx, opensource, programación

Adios NetBeans 6.9, hola Eclipse Ganymede + Exadel JavaFX plugin

Domingo, 6 de junio de 2010

Instalando el plugin para Eclipse de JavaFX

¿Será que Exadel mejorará el soporte de JavaFX en Eclipse?


La última gota que derramo el vaso; NetBeans 9.6 beta se cayó en medio de una operación sencilla, sin correr ni siquiera JavaFX. Me tiene realmente irritado que ni siquiera puedo crear mis pruebas de JUnit, así que moví todo mi proyecto a Eclipse. Las pruebas de JUnit las hice en un momento pero ahora me encuentro que tengo que montar soporte JavaFX 1.3.

¿Será sencillo?
¿Será mejor que NetBeans 6.9?

No tengo nada en contra de NetBeans, de hecho yo lo utilicé mucho antes que Eclipse (cuando se llamaba Forte). Hay un grupo de gente dedicada a corregir errores, pero quiero ver si al fin puedo terminar este proyecto en vez de pasar el tiempo reiniciando mi IDE.

Como si todo fuera tan fácil; Resulta que el plugin de Exadel para Eclipse se tira 3 peos dando un mensaje de error que dice ‘bad .class version‘.

Vamos a ver si lo resuelvo hoy mismo, ¡sino no me quedará otra que seguir trabajando con JavaFX 1.2!

java, javafx, opensource, programación

¿En donde están los trabajos?: Java Swing vs JavaFX vs Flex vs Silverlight

Jueves, 6 de mayo de 2010

Si esto es un indicativo de donde invertir el tiempo, por los momentos Java Swing y Adobe Flex son opciones seguras. JavaFX está aún en pañales…

java, javafx , , , ,

Programando en JavaFX: Enlaces recomendados, libros y un poco de Alpha Geeks

Martes, 4 de mayo de 2010

Bueno, esta semana he estado tratando es escribir código en serio con JavaFX en vez de pedazos de código; El resultado ha sido una combinación de alegría (la plataforma promete mucho) y frustración (debido a que la documentación y ejemplos están rotos debido a que el API está cambiando).

JavaFX en este momento es una herramienta para Alpha Geeks. En serio. Pese a estar en su versión 1.3 aún hay cosas importantes por mejorar, ademas de que el API pareciera estar cambiando. Si a eso se le suma el hecho de que ningún vendedor le está dando soporte serio en los teléfonos celulares (a diferencia de Android) no creo que nadie lo tome en serio para un proyecto empresarial.

¿Está todo perdido? Yo creo que el primer lugar en donde JavaFX va a tener precedencia va a ser en el escritorio, antes que los celulares. Sin embargo una mejor integración con Java y Swing (hay muchísimo código que no se va a evaporar de la noche a la mañana) además de mejoras en el soporte de Eclipse y NetBeans son necesarias. Con todo y eso, un lenguaje fresco para hacer interfaces gráficas era necesario y JavaFX parece ser un paso en la dirección correcta.

Pero bueno, no me extiendo más y los dejo con lo que en mi opinión son los mejores enlaces y libros sobre el lenguaje:

  • JavaFX layout secrets (Amy Fowlert). En mi opinión lectura obligada para entender como funcionan, en especial si usted hace aplicaciones empresariales.
  • JavaFX in Action: Muy buenos ejemplos, buena cobertura del API. No es un libro de principantes, aunque es increíblemente fácil de digerir.
  • Sitio oficial de JavaFX: Es la referencia obligada, sin embargo desde que sacaron la versión 1.3 retiraron un montón de ejemplos debido a que el API cambió. Un fastidio :(
  • El blog de Jim Weaver: Tuve la suerte de estar en una clase con Jim en JavaOne del 2008. Es un evangelista del lenguaje, tiene mucha experiencia práctica (y un libro para respaldarlo, Pro JavaFX 1.2 Book). Mucha información útil en su blog.

¿Y usted, tiene algún recurso interesante que quiera compartir?

–Jose

javafx, programación , , ,