X

JavaFX 1.0 launched - access services hosted on embedded GlassFish



Today Sun announces the availability of href="http://www.sun.com/aboutsun/pr/2008-12/sunflash.20081204.1.xml">Java
FX 1.0.



JavaFX 1.0 is a rich client platform for creating and delivering href="http://en.wikipedia.org/wiki/Rich_Internet_Applications">Rich
Internet Applications across all screens (desktop, browser,
and mobile) of your life. It consists of the following key components:



cellspacing="2">
href="http://javafx.com/"> style="border: 0px solid ; width: 200px; height: 100px;" alt=""
src="//cdn.app.compendium.com/uploads/user/e7c690e8-6ff9-102a-ac6d-e4aebca50425/f4a5b21d-66fa-4885-92bf-c4e81c06d916/Image/9fe25bc65bdca5931b161432a6361cff/javafx_logo_color_1.jpg"> href="http://javafx.com/?intcmp=2253">
    • href="http://java.sun.com/javafx/1/reference/sdk-install/">JavaFX
      SDK includes JavaFX script compiler and runtime
      tools, and a host of libraries to create RIAs for desktop, browser and
      mobile platforms, command-line tools & Ant tasks and other
      goodies.
    • href="http://java.sun.com/javafx/1/reference/javafx-netbeans-install/install-nb6.5-for-javafx.html">NetBeans
      6.5 support (as plugin or bundled with IDE) that allows to
      build, preview and debug JavaFX applications using NetBeans IDE. If you
      prefer CLI support then SDK can be downloaded.
    • href="http://java.sun.com/javafx/1/reference/production-suite-install/">Production
      Suite is a suite of tools and plugins for creative tools
      (such as Illustrator CS3+) that allows graphical assets to be
      exported to JavaFX applications.

      The beauty of JavaFX is that its fully integrated with the Java Runtime
      and takes advantage of the performance and ubiquity of Sun's Java
      Runtime Environment that is installed on literally billions of devices
      worldwide. Hence, JavaFX applications will run on any desktop, browser,
      mobile device or any other connected device that runs the Java Runtime
      Environment.



      cellspacing="2">
      href="http://jersey.dev.java.net"> style="border: 0px solid ; width: 64px; height: 52px;" alt=""
      src="">
      This blog shows how to create a simple JavaFX
      application using NetBeans
      IDE
      . The application plays a movie, allows the
      viewer to cast a vote if they liked it, and see aggregate response from
      other viewers. The application is developed using NetBeans 6.5, JavaFX
      1.0 plugin, and coded using JavaFX Script. The voting engine
      is deployed as a RESTful Web service using href="http://jersey.dev.java.net/">Jersey on href="http://glassfish.org/">GlassFish.



      In terms of
      user experience, running the NetBeans project shows a window playing
      the movie. The first mouse hover over the window allows the viewer to
      click
      on "I love it" or "Not so great" and cast their vote as shown below:



      src="//cdn.app.compendium.com/uploads/user/e7c690e8-6ff9-102a-ac6d-e4aebca50425/f4a5b21d-66fa-4885-92bf-c4e81c06d916/Image/bb9f04120b3691555a5fe653713d0415/javafx1_0_nb65_movie_vote.png">



      Any subsequent
      mouse hover shows aggregated
      results from other viewers as shown below:



      src="//cdn.app.compendium.com/uploads/user/e7c690e8-6ff9-102a-ac6d-e4aebca50425/f4a5b21d-66fa-4885-92bf-c4e81c06d916/Image/d9e558d2d2a8eb071aca69e0a5aab46b/javafx1_0_nb65_movie_result.png">



      The results are not interesting if there is a single viewer of the
      movie. But for a production environment, this movie will be played by
      multiple users concurrently and the percentage numbers will be more
      meaningful. You can close the window and run the project again to vote
      again, as many times as you like :)



      For those who like to see quick results, here is a 4-step guide to get
      started:

      1. In NetBeans 6.5 IDE, install JavaFX plugin as explained href="#javafx-plugin">here and RESTful
        Web services plugin as explained href="newblog4.html#jersey-plugin">here. Both the
        plugins may be installed in one step by selecting the required plugins
        together.
      2. Download NetBeans project for JavaFX client from href="http://blogs.sun.com/arungupta/resource/javafx/JavaFXApplication1.zip">here
        and add Jersey dependencies as explained in href="#jersey-dependencies">bullet #5
        below. 
      3. Download Web service endpoint Maven project from href="http://blogs.sun.com/arungupta/resource/javafx/movie-feedback-webapp.zip">here
        and deploy the endpoint as explained in bullet
        #4
        below.
      4. Run the JavaFX application as explained here.


      The remainder of this blog explains the details and shows how to
      construct the demo from scratch.



      Lets first create the JavaFX application that plays the video movie.

      1. In NetBeans
        6.5, install "JavaFX SDK" plugin.  In
        the "Tools"
        menu, "Plugins", search on "JavaFX", select "JavaFX SDK" and click on
        "Install".
      2. Create a new project of type "JavaFX", "JavaFX Script
        Application". Take the default values as shown below:

        src="//cdn.app.compendium.com/uploads/user/e7c690e8-6ff9-102a-ac6d-e4aebca50425/f4a5b21d-66fa-4885-92bf-c4e81c06d916/Image/c4256f16f0680cdff3cc09fc3efd43a1/javafx1_0_nb65_new_app.png">


        and click on "Finish".
      3. The source code for this class can be downloaded from href="http://blogs.sun.com/arungupta/resource/javafx/Main.fx">here
        or alternatively constructed as explained in the sub-bullets.
        1. In the newly created class, change the Stage (root area
          for
          all scene content) to:

          style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
          cellpadding="2" cellspacing="2">Stage {

             title: "GlassFish Media Player"

             width: 625

             height: 360

             resizable: false

             scene:
          myScene


          }
        2. Create a scene that contains the view of the media to be
          played and controls the display of the Vote or Result nodes:

          style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
          cellpadding="2" cellspacing="2">var myScene: Scene = Scene {

             content: MediaView {

                    
          fitWidth: 625

                    
          fitHeight: 360

                    mediaPlayer:
          bind myPlayer



                    
          onMouseEntered: function( e: MouseEvent ):Void {

                        
          println("mouse entered");

                        
          if (voted == false) {

                              style="font-weight: bold;">insert Vote{} into
          myScene.content;

                        
          } else {

                            insert
          Result{}
          into myScene.content;


                        
          }

                    
          }


                    
          onMouseExited: function( e: MouseEvent ):Void {

                        
          delete myScene.content[1]

                    
          }


                 }

          }
        3. Create a Media Player to use with the scene:

          style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
          cellpadding="2" cellspacing="2">var myPlayer: MediaPlayer = MediaPlayer{

              autoPlay: true

              media:
          bind myMedia


          };
        4. Create the media object to be used with the Media Player:

          style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
          cellpadding="2" cellspacing="2">var myMedia: Media = Media {

              source:
          "http://sun.edgeboss.net/download/sun/media/1460825906/1460825906_2957290001_DayEarth-Bluray.flv"


             };

          You can change the location of the movie here in the media player. For
          example, changing it to
          "http://mediacast.sun.com/users/ArunGupta/media/v3prelude-nb65-webapp.flv"
          will start playing the href="http://blogs.sun.com/arungupta/entry/screencast_27_simple_web_application">screencast
          #27.
        5. Create a Vote class that is a CustomNode and appears when
          a
          user's mouse enters the scene where the video is playing. The user can
          select whether he likes the clip or not and the vote is recorded
          making a Web service call using href="http://blogs.sun.com/arungupta/entry/totd_57_jersey_client_api">Jersey
          Client APIs:

          style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
          cellpadding="2" cellspacing="2">class Vote extends CustomNode {

             override function create():Node {

                 return
          Group {

                    
          content: [

                        
          Rectangle {

                            
          fill: Color.GREEN

                            
          x: 185

                            
          y: 145

                            
          width: 243

                            
          height: 38

                            
          arcWidth: 20

                            
          arcHeight: 20

                        
          },


                        
          Text {

                            
          x: 195

                            
          y: 170

                            
          fill: Color.WHITE

                            
          font: Font {

                                
          size: 18

                            
          }

                            
          content: "I love it"

                        
          },


                        
          Rectangle{

                            
          x: 191

                            
          y: 148

                            
          smooth: false

                            
          width: 73

                            
          height: 32

                            
          fill: Color.TRANSPARENT


                            
          onMouseClicked: function( e: MouseEvent ):Void {

                                
          println("clicked I love it");

                                
          voted = true;

                                wsClient.voteLoveIt();

                                
          delete myScene.content[1]

                            
          }

                        
          },


                        
          Text{

                            
          x: 305

                            
          y: 170

                            
          fill: Color.WHITE

                            
          font: Font {

                                
          size: 18

                            
          }

                            
          content: "Not so great"

                            
          },


                        
          Rectangle {

                            
          x: 301

                            
          y: 148

                            
          smooth: false

                            
          width: 118

                            
          height: 32

                            
          fill: Color.TRANSPARENT

                            

                            
          onMouseClicked: function( e: MouseEvent ):Void {

                                
          voted = true;

                                
          println("clicked Not so great");

                                wsClient.voteNotSoGreat();

                                
          delete myScene.content[1]

                            
          }

                        
          }

                    
          ]

                 }

             }

          };
        6. Create a Result class that is a CustomNode and simply
          reports on how many voters like this clip:

          style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
          cellpadding="2" cellspacing="2">class Result extends CustomNode {

             override function create():Node {

                 style="font-weight: bold;">var resultPercent =
          wsClient.showResults();

                 style="font-weight: bold;">var resultString =
          "{resultPercent} voters liked this clip";


                 return
          Group {

                    
          content: [

                        
          Rectangle {

                            
          fill: Color.BLUE

                            
          x: 187

                            
          y: 145

                            
          width: 244

                            
          height: 38

                            
          arcWidth: 20

                            
          arcHeight: 20


                            
          onMouseClicked: function( e: MouseEvent ):Void {

                                
          delete myScene.content[1]

                            
          }

                        
          },


                        
          Text {

                            
          x: 199

                            
          y: 170

                            
          fill: Color.WHITE

                            
          font: Font {

                                
          size: 18

                            
          }

                            content:
          resultString


                        
          }

                    
          ]

                 }

             }

          };
        7. Add two instance variables:

          style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
          cellpadding="2" cellspacing="2">var voted = false;

          var wsClient = new WebserviceClient;

          The first variable captures if the viewer has already voted and the
          second variable is an instance to the RESTful Web service client.
        8. Add the following import statements:

          style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
          cellpadding="2" cellspacing="2">import javafx.scene.\*;

          import javafx.scene.input.MouseEvent;

          import javafx.scene.media.Media;

          import javafx.scene.media.MediaPlayer;

          import javafx.scene.media.MediaView;

          import javafx.scene.paint.Color;

          import javafx.scene.shape.Rectangle;

          import javafx.scene.text.Font;

          import javafx.scene.text.Text;

          import javafx.stage.Stage;

          "Fix Imports" should be able to fix them and href="http://www.netbeans.org/issues/show_bug.cgi?id=154307">bug
          #154307 is already filed for that.
      4. Create a new class that is used to capture the Vote as:

        style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
        cellpadding="2" cellspacing="2">@javax.xml.bind.annotation.XmlRootElement

        public class VoteBean {

            public static enum VOTE { LOVE_IT,
        NOT_SO_GREAT };

           

            public VOTE vote;


            public VoteBean() { vote = VOTE.LOVE_IT;
        }

            public VoteBean(VOTE vote) {

               
        this.vote = vote;

            }

        }

        This is a simple Javabean with a standard JAXB annotation.
        This ensures that XML is used as the data format for transfering
        results between client and endpoint. The source code for this class is
        available href="http://blogs.sun.com/arungupta/resource/javafx/VoteBean.java">here.
      5. Add
        Jersey libraries to the project by right-clicking on
        Project, select Libraries, click on "Add Library...", select "JAX-RS
        1.0" and "Jersey 1.0 (JAX-RS RI)", and click on "Add Library".

        href="//cdn.app.compendium.com/uploads/user/e7c690e8-6ff9-102a-ac6d-e4aebca50425/f4a5b21d-66fa-4885-92bf-c4e81c06d916/Image/1d2835e51e4cdae98246c24229c2bb95/javafx1_0_nb65_add_jersey_client_libs.png"> style="border: 0px solid ; width: 700px; height: 500px;" alt=""
        src="//cdn.app.compendium.com/uploads/user/e7c690e8-6ff9-102a-ac6d-e4aebca50425/f4a5b21d-66fa-4885-92bf-c4e81c06d916/Image/1d2835e51e4cdae98246c24229c2bb95/javafx1_0_nb65_add_jersey_client_libs.png">

        If these libraries
        are not available then install the "RESTful Web
        Services" plugin from the Plugin Center.
      6. And finally add the class that invokes the RESTful
        Webservice
        endpoint:

        cellpadding="2" cellspacing="2">
        public
        class WebserviceClient {


            private static style="font-weight: bold;">com.sun.jersey.api.client.WebResource
        createWebResource() {

               
        return com.sun.jersey.api.client.Client.create().

                       
        resource("http://localhost:8080/movie-feedback-webapp/webresources/myresource");

            }


            public static void voteLoveIt() {

               
        createWebResource().type("application/json").

                       post(new
        VoteBean(VoteBean.VOTE.LOVE_IT))
        ;

            }


            public static void voteNotSoGreat() {

               
        createWebResource().type("application/json").

                       post(new
        VoteBean(VoteBean.VOTE.NOT_SO_GREAT))
        ;

            }


            public static String showResults() {

               
        return createWebResource().get(String.class);

            }

        }


        The Webservice endpoint will be hosted at
        "http://localhost:8080/movie-feedback-webapp/webresources/myresource".
        A WebResource is created from the Client. The POST methods are used to
        cast the user vote and GET method is used to retrieve the aggregated
        results. The source code for this class is available href="http://blogs.sun.com/arungupta/resource/javafx/WebserviceClient.java">here.


      Now lets create the RESTful endpoint using Jersey and deploy on
      GlassFish.

      1. Create and deploy a RESTful Web service endpoint
        1. Create a template RESTful Web service endpoint as
          described in href="http://blogs.sun.com/arungupta/entry/totd_56_simple_restful_web">TOTD
          #56. Lets use the artifactId as "movie-feedback-webapp".
        2. Create the bean "VoteBean" in "org.glassfish.samples"
          package. This is the exactly same bean used earlier by the client:

          style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
          cellpadding="2" cellspacing="2">@javax.xml.bind.annotation.XmlRootElement

          public class VoteBean {

              public static enum VOTE { LOVE_IT,
          NOT_SO_GREAT };

              public VOTE vote;


              public VoteBean() { vote = VOTE.LOVE_IT;
          }

              public VoteBean(VOTE vote) {

                 
          this.vote = vote;

              }

          }
        3. Update the generated resource
          1. Add href="https://jersey.dev.java.net/source/browse/\*checkout\*/jersey/tags/jersey-1.0/api/jersey/com/sun/jersey/spi/resource/Singleton.html">@com.sun.jersey.spi.resource.Singleton
            as class annotation so that only one instance of the resource is
            created for the entire web
            application. This allows to save state (preferences from other users)
            in the RESTful resource.
          2. Add two instance variables:

            style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
            cellpadding="2" cellspacing="2">    int loveIt;

                int noSoGreat;
          3. Add a method that will process HTTP POST requests as:

            style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
            cellpadding="2" cellspacing="2">    @POST

                public void postOneVote(VoteBean bean) {

                   
            if (bean.vote == VoteBean.VOTE.LOVE_IT) {

                       
            loveIt++;

                   
            } else {

                       
            noSoGreat++;

                    }

                   
            System.out.println("In POST: " + bean.vote);

                }

            This method stores the vote in the resource. The handling of POST
            request messages by Jersey is explained in href="http://blogs.sun.com/arungupta/entry/totd_58_jersey_and_glassfish">TOTD
            #58.
          4. Add a method that will process HTTP GET requests as:

            style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
            cellpadding="2" cellspacing="2">    @GET

                @Produces("text/plain")

                public String getOpinion() {

                   
            if (loveIt == 0 && noSoGreat == 0)

                       
            return "No votes cast yet!";

                   
            return (loveIt \* 100) / (loveIt + noSoGreat) + "%";

                }

            This method calculates the percentage of viewers who liked the movie.
        4. Deploy the
          endpoint using "mvn glassfish:run" in
          "movie-feedback-webapp" directory.


      Now run the JavaFX application by
      right-clicking on the project and
      selecting "Run Project" and start voting! The percentage
      results will vary if the movie is voted upon more than once.



      This blog showed:
      • How to install JavaFX capabilities to an existing NetBeans
        6.5 installation
      • How to create a simple JavaFX application that plays media
        files
      • Integrate it with existing Java libraries (Jersey client
        libraries in this case)
      • Invoke services hosted on GlassFish

      The steps followed in this blog allows for rapid development/debugging
      of JavaFX application accessing resources using embeddable GlassFish
      but are not ideal for production deployments. A future
      blog will show how this JavaFX application can be deployed as a href="http://java.sun.com/javase/technologies/desktop/javawebstart/index.jsp">Java
      Web Start application and scaled for mulitple users.



      The javafx.com/samples
      has loads of samples and javafx.com/tutorials
      shows how to build your own applications. The href="http://jfx.wikia.com/wiki/The_JavaFX_Community">JavaFX
      Community Wiki is a great place to collaborate.



      Send your Jersey questions to href="mailto:users@jersey.dev.java.net">users@jersey.dev.java.net,
      GlassFish questions to href="http://forums.java.net/jive/forum.jspa?forumID=56&start=0">GlassFish
      Forum, and JavaFX questions to href="http://forums.sun.com/category.jspa?categoryID=132">JavaFX
      Forums.



      Technorati:
      glassfish
      v3
      jersey
      webservices
      javafx netbeans

      Join the discussion

      Comments ( 14 )
      • Wim Flory Thursday, December 4, 2008

        Pity it is not available for Linux/Ubuntu,

        Why release JavaFX for windows before releasing it for Linux and Solaris?


      • Arun Gupta Thursday, December 4, 2008

        Linux and Solaris support are being actively worked upon. Please read more details at:

        http://blogs.sun.com/javafx/entry/a_word_on_linux_and


      • Robert Thursday, December 4, 2008

        You want to have quick return around your business with new technology and quality way so get concerd to Real assistance.com <a href="http://www.realdataassistance.com/">Data entry service providers</a>


      • Stefan Monday, December 8, 2008

        Great tutorial, and it almost looks like javafx is not that silly, as it sounded when we first heard the announcement. I'm still waiting for a compelling reason to use it instead of flex/gwt/your-favorite-ajax-framework, but at least you can get your job done with fx, too.

        PS: May I propose a printing-style-sheet that switches of the right navigation-bar!? I love your tutorials and would love them even more if I could print them and read them over breakfast...


      • Robert Tuesday, December 9, 2008

        I can't see the video also I can here the sound.


      • Arun Gupta Tuesday, December 9, 2008

        Stefan, good suggestion and I'll try to incorporate it.

        Robert, are you connected to Internet when playing the video ? Is there any error in the console ?


      • Robert Tuesday, December 9, 2008

        Yes, I have a working Internet connection and there are no errors in the console. And I'm hearing sound.


      • Arun Gupta Tuesday, December 9, 2008

        Hmm, the location is embedded in src/javafxapplication1/Main.fx and is ""http://sun.edgeboss.net/download/sun/media/1460825906/1460825906_2957290001_DayEarth-Bl

        uray.flv". Can you play the video directly in your browser ?

        Anything beyond that, you may have to ask your question on JavaFX forums:

        http://forums.sun.com/category.jspa?categoryID=132


      • dizi izle Saturday, February 21, 2009

        ThankSs


      • sinema izle Saturday, March 7, 2009

        thx u.


      • Pat Patterson Wednesday, April 22, 2009

        Hey Arun - do you know if the Jersey client stuff works on JavaFX Mobile???


      • Arun Gupta Wednesday, April 22, 2009

        Pat, I've not tried and Google also does not show up anything. Try asking the question on users@jersey.


      • Pat Patterson Tuesday, April 28, 2009

        To answer my own question - no - Jersey client doesn't work on JavaFX Mobile - my test program (working on JavaFX Desktop) fails with "class file for java.net.URI not found". Unsurprising, since java.net.\* is not in Java ME. Oh well - back to javafx.data.pull.PullParser.


      • resimler Thursday, March 11, 2010

        Yes, I have a working Internet connection and there are no errors in the console. And I'm hearing sound.


      Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha
      Oracle

      Integrated Cloud Applications & Platform Services