{"id":3109,"date":"2011-10-09T18:32:20","date_gmt":"2011-10-10T01:32:20","guid":{"rendered":"http:\/\/kodegeek.com\/blog\/?p=3109"},"modified":"2011-10-11T03:43:33","modified_gmt":"2011-10-11T10:43:33","slug":"jython-javafx-comienzo-duro","status":"publish","type":"post","link":"http:\/\/kodegeek.com\/blog\/2011\/10\/09\/jython-javafx-comienzo-duro\/","title":{"rendered":"Jython + JavaFX: Comienzo duro"},"content":{"rendered":"<p>Al fin Oracle liber\u00f3 su versi\u00f3n final de JavFX en JavaOne 2011; Tambi\u00e9n hay una versi\u00f3n beta para OSX la cual me baje de una vez.<\/p>\n<p>Jugando con los ejemplos me dediqu\u00e9 a experimentar con <a title=\"Gr\u00e1fico de Torta con JavaFX\" href=\"http:\/\/download.oracle.com\/javafx\/2.0\/charts\/pie-chart.htm#CIHFDADD\" target=\"_blank\">el ejemplo de un gr\u00e1fico de torta<\/a> el cual se ve sencillo:<\/p>\n<pre lang=\"Java\">import javafx.application.Application;\r\nimport javafx.collections.FXCollections;\r\nimport javafx.collections.ObservableList;\r\nimport javafx.scene.Scene;\r\nimport javafx.stage.Stage;\r\nimport javafx.scene.chart.PieChart;\r\nimport javafx.scene.Group;\r\n\r\npublic class PieChartSample extends Application {\r\n\r\n    @Override public void start(Stage stage) {\r\n        Scene scene = new Scene(new Group());\r\n        stage.setTitle(\"Imported Fruits\");\r\n        stage.setWidth(500);\r\n        stage.setHeight(500);\r\n\r\n        ObservableList pieChartData =\r\n                FXCollections.observableArrayList(\r\n                new PieChart.Data(\"Grapefruit\", 13),\r\n                new PieChart.Data(\"Oranges\", 25),\r\n                new PieChart.Data(\"Plums\", 10),\r\n                new PieChart.Data(\"Pears\", 22),\r\n                new PieChart.Data(\"Apples\", 30));\r\n        final PieChart chart = new PieChart(pieChartData);\r\n        chart.setTitle(\"Imported Fruits\");\r\n\r\n        ((Group) scene.getRoot()).getChildren().add(chart);\r\n        stage.setScene(scene);\r\n        stage.show();\r\n    }\r\n\r\n    public static void main(String[] args) {\r\n        launch(args);\r\n    }\r\n}<\/pre>\n<p>Lo compilamos y corremos:<\/p>\n<pre lang=\"Bash\">Macintosh:javafx josevnz$ export CLASSPATH=\/Users\/Shared\/javafx-sdk2.0.2-beta\/\/rt\/lib\/jfxrt.jar:.\r\nMacintosh:javafx josevnz$ javac PieChartSample.java -d .\r\nMacintosh:javafx josevnz$ java PieChartSample<\/pre>\n<p><a href=\"http:\/\/kodegeek.com\/blog\/wp-content\/uploads\/2011\/10\/Screen-Shot-2011-10-09-at-9.19.06-PM.png\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/kodegeek.com\/blog\/wp-content\/uploads\/2011\/10\/Screen-Shot-2011-10-09-at-9.19.06-PM.png\" alt=\"JavaFX Pie chart\" title=\"JavaFX Pie chart\" width=\"612\" height=\"604\" class=\"alignnone size-full wp-image-3114\" srcset=\"http:\/\/kodegeek.com\/blog\/wp-content\/uploads\/2011\/10\/Screen-Shot-2011-10-09-at-9.19.06-PM.png 612w, http:\/\/kodegeek.com\/blog\/wp-content\/uploads\/2011\/10\/Screen-Shot-2011-10-09-at-9.19.06-PM-300x296.png 300w\" sizes=\"(max-width: 612px) 100vw, 612px\" \/>JavaFX gr\u00e1fico de torta en acci\u00f3n<br \/>\n<\/a><\/p>\n<p>As\u00ed que trat\u00e9 de convertir este sencillo c\u00f3digo a Jython:<\/p>\n<pre lang=\"Python\">\r\n#!\/usr\/bin\/env jython\r\nimport sys\r\nfrom javafx.application import Application\r\nfrom javafx.collections import FXCollections\r\nfrom javafx.collections import ObservableList\r\nfrom javafx.scene import Scene\r\nfrom javafx.stage import Stage\r\nfrom javafx.scene.chart import PieChart\r\nfrom javafx.scene import Group\r\n\r\nclass PieChartSample(Application):\r\n\r\n    def __init__(self):\r\n        pass\r\n\r\n    def start(self, stage):\r\n        scene = Scene(Group())\r\n        stage.setTitle(\"Imported Fruits\")\r\n        stage.setWidth(500)\r\n        stage.setHeight(500)\r\n\r\n        pieChartData = FXCollections.observableArrayList(\r\n                PieChart.Data(\"Grapefruit\", 13),\r\n                PieChart.Data(\"Oranges\", 25),\r\n                PieChart.Data(\"Plums\", 10),\r\n                PieChart.Data(\"Pears\", 22),\r\n                PieChart.Data(\"Apples\", 30))\r\n        chart = PieChart(pieChartData)\r\n        chart.setTitle(\"Imported Fruits\")\r\n\r\n        scene.getRoot().getChildren().add(chart)\r\n        stage.setScene(scene)\r\n        stage.show()\r\n\r\nif __name__ == \"__main__\":\r\n        PieChartSample().launch(sys.argv[1:])\r\n<\/pre>\n<p>Pero al correrlo me se queja que no estoy extendiendo bien la clase &#8216;Aplication&#8217; y por eso falla:<\/p>\n<pre lang=\"Bash\">\r\nMacintosh:javafx josevnz$ .\/piechart.py \r\n*sys-package-mgr*: can't create package cache dir, '\/Users\/Shared\/jython2.5.2\/cachedir\/packages'\r\nTraceback (most recent call last):\r\n  File \".\/piechart.py\", line 36, in <module>\r\n    PieChartSample().launch(sys.argv[1:])\r\n\tat javafx.application.Application.launch(Application.java:186)\r\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)\r\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)\r\n\tat java.lang.reflect.Method.invoke(Method.java:597)\r\n\r\njava.lang.RuntimeException: java.lang.RuntimeException: Error: class sun.reflect.NativeMethodAccessorImpl is not a subclass of javafx.application.Application\r\n\r\n<\/module><\/pre>\n<p>No tengo ni idea en donde esta el error, \u00bfalguno de ustedes tiene una pista? De verdad me muero de ganas por usar JavaFX con Jython, ya otros han tenido \u00e9xito similar con <a href=\"http:\/\/download.oracle.com\/javafx\/2.0\/jruby\/jfxpub-jruby.htm\">JRuby<\/a> y <a href=\"http:\/\/groovy.codehaus.org\/GroovyFX\">Groovy<\/a>.<\/p>\n<p>Amanecer\u00e1 y veremos.<\/p>\n<p><strong>Actualizaci\u00f3n<\/strong>: De la lista de Jython me llegaron muchas sugerencias, al final Weiqi Gao encontr\u00f3 cual era el verdadero problema y esta es la soluci\u00f3n:<\/p>\n<pre lang=\"Java\">\r\n# The key to happiness in JavaFX + Jython is this:\r\nif __name__ == \"__main__\":\r\n    Application.launch(PieChartSample().class, sys.argv[1:])\r\n<\/pre>\n<p>La explicaci\u00f3n detallada a continuaci\u00f3n:<\/p>\n<blockquote><p>\nThe 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:<\/p>\n<pre lang=\"Java\">\r\npublic static void launch(String[] args);\r\n<\/pre>\n<p>and<\/p>\n<pre lang=\"Java\">\r\npublic static void launch(Class< ? extends Application> appClass, String[] args);\r\n<\/pre>\n<p>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.<\/p>\n<p>The idiom for using the first version of launch() in Java is the following:<\/p>\n<pre lang=\"Java\">\r\npublic class Foo extends Application {\r\n    @Override\r\n    public void start(Stage stage) {\r\n      \/\/ build the scene graph and show it\r\n    }\r\n\r\n    public static void main(String[] args) {\r\n      Application.launch(args); \r\n    }\r\n}\r\n<\/pre>\n<p>The idiom for using the second version of launch() in Java is the following:<\/p>\n<pre lang=\"Java\">\r\npublic class Foo extends Application {\r\n  @Override\r\n  public void start(Stage stage) {\r\n    \/\/ build the scene graph and show it\r\n  }\r\n}\r\n\r\npublic class Launcher {\r\n  public static void main(String[] args) {\r\n    Application.launch(Foo.class, args);\r\n  }\r\n}\r\n<\/pre>\n<p>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&#8217;t think of how at the moment.\n<\/p><\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>Al fin Oracle liber\u00f3 su versi\u00f3n final de JavFX en JavaOne 2011; Tambi\u00e9n hay una versi\u00f3n beta para OSX la cual me baje de una vez. Jugando con los ejemplos me dediqu\u00e9 a experimentar con el ejemplo de un gr\u00e1fico de torta el cual se ve sencillo: import javafx.application.Application; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.scene.Scene; <a class=\"read-more\" href=\"http:\/\/kodegeek.com\/blog\/2011\/10\/09\/jython-javafx-comienzo-duro\/\">[&hellip;]<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[9,561,239],"tags":[684],"_links":{"self":[{"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/posts\/3109"}],"collection":[{"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/comments?post=3109"}],"version-history":[{"count":12,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/posts\/3109\/revisions"}],"predecessor-version":[{"id":3121,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/posts\/3109\/revisions\/3121"}],"wp:attachment":[{"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/media?parent=3109"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/categories?post=3109"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/tags?post=3109"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}