★ wanayoo — archive 1999 https://blogs.oracle.com/thejavatutorials/category/GeneralNouvelle recherche | Portail wanayoo

Wednesday Mar 06, 2013

Java Tutorials Fifth Edition Book

The JDK documentation team is happy to announce that The Java® Tutorial, Fifth Edition book is now available on Amazon in printed book and kindle formats. The fifth edition is based on JDK 7 and contains tutorials and code samples for the following features and more:
  • New file I/O API (NIO.2) and migrating legacy code to the new API
  • Fork Join pool
  • Project Coin: try-with-resources statement, binary literals, diamond syntax
  • Updates to Generics tutorial
  • Expanded deployment coverage (applets, java web start applications)
  • Preparing for Java Programming Language Certification - A mapping of Java certification objectives to sections of the Java Tutorials.

- Sowmya

Thursday Dec 13, 2012

JavaFX 2.2.4 Documentation

JavaFX 2.2.4 and JDK 7u10 were released on Tuesday. In addition to the release documentation, the following new information is provided:

  • A new document, Using the Image Ops API, describes how to read and write raw pixel data to and from JavaFX images.
  • The Handling JavaFX Events document has been updated with more information on touch events. The Working with Touch Events chapter and Touch Events sample provide information about handling individual touch points to provide sophisticated responses to touch actions.
  • The Implementing Best Practices document has been updated to include information about running tasks on background threads.
  • The Troubleshooting section of Deploying JavaFX Applications now includes a section about disabling the automatic proxy configuration in your application code.

Other documents were updated to reflect minor bug fixes.

You can download JavaFX 2.2.4 from OTN. For all tutorials and API documentation, see http://docs.oracle.com/javafx.

Friday Aug 24, 2012

Take a snapshot with JavaFX!

JavaFX 2.2 has a "snapshot" feature that enables you to take a picture of any node or scene. Take a look at the API Documentation and you will find new snapshot methods in the javafx.scene.Scene class.

The most basic version has the following signature:

public WritableImage snapshot(WritableImage image)

The WritableImage class (also introduced in JavaFX 2.2) lives in the javafx.scene.image package, and represents a custom graphical image that is constructed from pixels supplied by the application.

In fact, there are 5 new classes in javafx.scene.image:

  • PixelFormat: Defines the layout of data for a pixel of a given format.
  • WritablePixelFormat: Represents a pixel format that can store full colors and so can be used as a destination format to write pixel data from an arbitrary image.
  • PixelReader: Defines methods for retrieving the pixel data from an Image or other surface containing pixels.
  • PixelWriter: Defines methods for writing the pixel data of a WritableImage or other surface containing writable pixels.
  • WritableImage: Represents a custom graphical image that is constructed from pixels supplied by the application, and possibly from PixelReader objects from any number of sources, including images read from a file or URL.

The API documentation contains lots of information, so go investigate and have fun with these useful new classes!

-- Scott Hommel

Tuesday Jun 19, 2012

JavaFX 2.1.1 Documentation

JavaFX 2.1.1 released on June 12, and few documents were updated on the docs.oracle.com/javafx website.

Besides a new set of release documentation, the Concurrency in JavaFX article was updated with a discussion of how to cancel a task, with a code sample to illustrate that. A new section describes the WorkerStateEvent class and how to use the convenience methods such as cancelled, failed, running, scheduled, and succeeded, which are invoked when the Worker implementation state changes.

Other documents were updated to reflect minor bug fixes, many of them contributed by JavaFX readers using the feedback alias in the sidebar of all of our documentation. Yes, we do respond and pay attention to what you say and at least try to point you in the right direction if we can't solve a problem you're having with a tutorial. We appreciate your feedback!

Friday Nov 18, 2011

JavaFX: Use a Screen with your Scene!

Here's a handy tip for sizing your application. You can use the javafx.stage.Screen class to obtain the width and height of the user's screen, and then use those same dimensions when sizing your scene. The following code modifies default "Hello World" application that appears when you create a new JavaFX project in NetBeans.

package screendemo;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;
import javafx.stage.Screen;
import javafx.geometry.Rectangle2D;

public class ScreenDemo extends Application {

    public static void main(String[] args) {
        Application.launch(args);
    }
    
    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Hello World");
        Group root = new Group();
        Rectangle2D screenBounds = Screen.getPrimary().getVisualBounds();
        Scene scene = new Scene(root, screenBounds.getWidth(), screenBounds.getHeight());   
        Button btn = new Button();
        btn.setLayoutX(100);
        btn.setLayoutY(80);
        btn.setText("Hello World");
        btn.setOnAction(new EventHandler() {

            public void handle(ActionEvent event) {
                System.out.println("Hello World");
            }
        });
        root.getChildren().add(btn);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

Running this program will set the Stage boundaries to visible bounds of the main screen.

-- Scott Hommel

Thursday Oct 27, 2011

Share Your Ideas!

JavaFX 2.0 Documentation

Thanks to our JavaFX readers who have submitted feedback on the documentation. Our latest release of the JavaFX documentation includes improvements and fixes suggested by our readers. For example, we added a deployment section to the Getting Started tutorial and put more diagrams in the Deployment document.

You can send us feedback from any JavaFX document.  Look for the section titled "We Welcome Your Feedback" in the document right nav bar, as shown in the following figure.

User Feedback Section

Share your ideas on what, from your perspective, needs to be documented.
Which essential concepts are not covered yet?

Help us to help you!

Monday Oct 03, 2011

JavaFX 2.0 Released!

JavaFX 2.0, a major update to JavaFX, has been designed from the ground-up to be the next generation UI platform for Java developers. It provides a powerful and expressive Java-based UI platform capable of handling large-scale data-driven business applications.

It offers developers an easy to learn UI platform to create rich Internet applications and content for desktops and web browsers. Starting with this version, developers can create JavaFX applications completely in the Java programming language using standard Java development tools, while leveraging their existing investments and knowledge in the Java platform.

JavaFX 2.0 includes a rich set of UI controls, graphics and media features to simplify development of immersive visual applications. A new feature introduced in JavaFX 2.0 is the WebView component that allows embedding web content in JavaFX applications. In addition, JavaFX allows developing user interfaces in FXML – a scriptable, XML-based markup language for defining user interfaces. Developers familiar with web technologies or other markup based UI technologies will find FXML easy to learn and powerful for a variety of applications.

The documentation set for JavaFX 2.0 contains over 30 new and updated documents, including new coverage of Drag-and-Drop and the JavaFX Collections API. It also includes a redesigned index page with a new learning trail, and a customized feedback box on each doc. The documentation set is arranged into the following categories: Getting Started; User Interface; Effects, Animation, and Media; Application Logic; Reference; Deployment and More.

JavaFX 2.0 is now available for download from javafx.com. For detailed tutorials and API documentation, see http://download.oracle.com/javafx.

Wednesday Nov 25, 2009

Java Applets Quiz

Do you enjoy quizzes? Take a minute to answer this quiz about Java applets.[Read More]

Tuesday Nov 24, 2009

Getting Applets To Talk To Each Other

Do you have more than one applet on a web page? Do you want the applets to share water cooler gossip? Ahem..ahem.. On a more serious note, do you want one applet to invoke methods or set variables of another applet? [Read More]

Tuesday Nov 17, 2009

Reader Poll: Who Wants Screencasts?

Hi everyone,

We're running a reader poll over on the JavaFX blog. We'd like to know your thoughts on screencasting vs. written tutorials. Please take a minute to visit that page and leave a comment. We greatly value your opinion!

- Scott Hommel

Wednesday Sep 09, 2009

Follow Scott on Twitter!

Hey everyone, this is Scott Hommel. I've been a member of the docs team here at Sun for the past decade, working on both the JDK docs and the Java Tutorial. Since '07 I've been assigned exclusively to JavaFX (http://www.javafx.com). I've set up a twitter account at http://www.twitter.com/scotthommel so if you've ever been curious about the day-to-day workings of a technical writer, sign up to "follow" what I'm working on. It'll give you the inside scoop on what docs are coming out next. With enough followers, perhaps other writers will start "tweeting" as well.

-- Scott Hommel

Wednesday May 27, 2009

Just released -- Java Tutorials update

To coincide with the JDK7 Preview Release and JavaOne, we have just published an updated version of the Java Tutorials. Besides fixing many typos and errors that you have reported, this release includes:

  • An entirely reworked File I/O lesson, featuring NIO.2. This functionality is part of JDK7, which is available now through the Open JDK project on java.net.
  • A new specialized trail covering Sockets Direct Protocol, also new in JDK7.
  • A new facility for gathering feedback about the tutorial. At the bottom of each tutorial page, under the "Discuss" heading, you can leave a publicly viewable, blog-style comment. Let us know what you think about the inclusion of this JS-Kit mechanism.

Thanks, as always, for your feedback. It helps us improve the tutorial!

-- Sharon Zakhour

Tuesday Feb 03, 2009

JavaBat -- Java Practice Programs

Wow, a very cool website was just brought to my attention. Nick Parlante, of Stanford, has pulled together a website where you can hone your Java skills.

Created with the theory that you learn by doing and the more you do it, the better you get, JavaBat provides a set of programming examples that give you immediate feedback. You can work through several examples in an hour — it compiles and runs your code using a variety of parameters so you can see where it fails. At the end, you can hop over to the "done" page and view your stats. Want to test your skills in a friendly, good-natured competition? Here ya go. :)

JavaBat is one of the neatest, free Java resources I've seen in a long time!

-- Sharon Zakhour

Thursday Jan 15, 2009

Inverse Kinematics Demo

Sun engineer Michael Heinrichs recently wrote a great animation demo that uses inverse kinematics to animate JavaFX objects. Check it out on his blog and feel free to leave a comment!

-- Scott Hommel

Friday Dec 12, 2008

JavaFX Coffee Cup

So the JavaFX™ SDK 1.0 has shipped. I thought that now would be a fun time to try out some of its graphics capabilities. I know that its graphics are really slick... but how easy are they to program? Do you need to be a graphics expert to figure it all out, or can anyone just pick it up and learn?

As for my background, I'm a technical writer and general-purpose computer programmer. I am not a software engineer, graphic designer, or GUI expert. Because of that I'm probably the ideal person to test drive the usability of GUI coding with the SDK. The challenge to myself was to take a single afternoon and code up something "impressive"; it didn't matter what, I just wanted it to have a 3D feel with modern visual/lighting effects like what I see in the SDK demos.

So the first thing I did was to read the GUI tutorial, which quickly brought me up to speed on the basics. (Those completely new to the JavaFX Script programming language will want to first read the core tutorial as well.) I then went to the web, looking for information on drawing 3D shapes in general.

I came across this article, which builds a 3D coffee cup using a freeware vector graphics drawing program called inkscape. Having a limited GUI background, this was exactly the kind of breakdown that I needed. It explained how to make "3D" looking objects from basic 2D shapes, filled in with various color gradients. The challenge to myself was to basically "port" their tool instructions to equivalent calls in the API. By the end of the afternoon, I'd made this cool looking cup:

Here's how I did it...

Making the Frame

Setting up the basic application frame was super easy to do. JavaFX technology lets you "group" multiple objects together, so I made one group for the plate, and another for the cup. These two groups will contain the graphical objects to be rendered on screen:

import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.Group;

def plateGroup = Group {
     // The group of objects forming the "plate" will go here
}

def cupGroup = Group {
    // The group of objects forming the "cup" will go here
}

Stage {
    title: "Coffee Cup"
    visible: true
    scene: Scene {
         width: 500
         height: 500
         content: [plateGroup,cupGroup]
     }
}

There's nothing to display yet, but the code is organized, and that's an important first step. I've used the def keyword to assign these groups to individual variables; this makes it easier to "unplug" a finished group (i.e. the plate) to work on the other (the cup) in isolation, if need be.

Making the Plate

The first step in making the plate was to draw an Ellipse, filled with a RadialGradient that spans three colors (Color.WHITESMOKE, Color.LIGHTGRAY, and Color.DARKGREY):

import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.paint.Color;
import javafx.scene.shape.\*;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;

def plateGroup = Group {

     translateX: 250
     translateY: 300

     content: [
          Ellipse {centerX: 0 centerY: 0  radiusX: 170 radiusY: 50
               fill: RadialGradient{
                         centerX: 0.5 centerY: 0.75
                         stops: [Stop {offset: 0.0 color: Color.WHITESMOKE},
                                 Stop {offset: 0.5 color: Color.LIGHTGRAY},
                                 Stop {offset: 1.0 color: Color.DARKGRAY}]
               } 
          } 
     ] 
}

def cupGroup = Group {
    // The group of objects forming the "cup" will go here
}

Stage {
    title: "Coffee Cup"
    visible: true
    scene: Scene {
         width: 500
         height: 500
         content: [plateGroup,cupGroup]
     }
}

The translateX and translateY variables of the Group object proved useful for moving the entire group around on screen. I found that getting the exact values for the gradient was just a matter of trial and error. There are a number of different settings that all looked good; finding something that looked "right" was just a matter of plugging in different values and recompiling the program.

Next I added a dark gray ellipse below the plate, and another thin ellipse to make the lip (giving it a 3D feel):

import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.paint.Color;
import javafx.scene.shape.\*;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;

def plateGroup = Group {

translateX: 250
translateY: 300

 content: [ 

          // The gray ellipse under the plate
          Ellipse{centerX: 0 centerY: 10 radiusX: 160 radiusY: 50 fill: Color.DIMGRAY},

          // The thin "lip" of the plate (provides a sense of 3D)
          Ellipse{centerX: 0 centerY: 3  radiusX: 170 radiusY: 50 fill: Color.LAVENDER}, 

          // The large plate ellipse
          Ellipse{centerX: 0 centerY: 0  radiusX: 170 radiusY: 50
          fill: RadialGradient{
                    centerX: 0.5 centerY: 0.75
                    stops:[Stop {offset: 0.0 color: Color.WHITESMOKE},
                           Stop {offset: 0.5 color: Color.LIGHTGRAY},
                           Stop {offset: 1.0 color: Color.DARKGRAY}]
               }
          }
     ]
}

def cupGroup = Group {
    // The group of objects forming the "cup" will go here
}

Stage {
    title: "Coffee Cup"
    visible: true
    scene: Scene {
         width: 500
         height: 500
         content: [plateGroup,cupGroup]
     }
}

Since GUI objects are rendered in the order they appear in the source code, I put the main plate ellipse last so that it would cover the tops of all the others. Again, finding the exact values was just a matter of experimentation.

Finally, I recessed the center of the plate:

import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.paint.Color;
import javafx.scene.shape.\*;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;

def plateGroup = Group {

translateX: 250
translateY: 300

 content: [

          // The gray ellipse under the plate
          Ellipse{centerX:0 centerY:10 radiusX:160 radiusY:50 fill:Color.DIMGRAY},

          // The thin "lip" of the plate (provides a sense of 3D)
          Ellipse{centerX:0 centerY:3  radiusX:170 radiusY:50 fill:Color.LAVENDER},

          // The large plate ellipse
          Ellipse{centerX:0 centerY:0  radiusX:170 radiusY:50
          fill:RadialGradient{
                    centerX:0.5 centerY:0.75
                    stops:[Stop {offset: 0.0 color: Color.WHITESMOKE},
                           Stop {offset: 0.5 color: Color.LIGHTGRAY},
                           Stop {offset: 1.0 color: Color.DARKGRAY}]
               }
          },

         // Recessed plate center
           Ellipse{centerX: 0 centerY: 5 radiusX: 90 radiusY: 22
                fill: RadialGradient{
                          centerX: 0.5 centerY: 0.75
                          stops:[Stop {offset: 0.0 color: Color.BLACK},
                                 Stop {offset: 0.4 color: Color.LIGHTGRAY},
                                 Stop {offset: 1.0 color: Color.GHOSTWHITE}]
                     }
          }
     ]
}

def cupGroup = Group {
    // The group of objects forming the "cup" will go here
}

Stage {
    title: "Coffee Cup"
    visible: true
    scene: Scene {
         width: 500
         height: 500
         content: [plateGroup,cupGroup]
     }
}

Without this dark shadow, the cup bottom would be hard to see when it's finally in place. In the end this darkened area will be more subtle because the cup will be hiding most of it.

Making the Cup

To make the cup, I just started with a Circle, giving it the the same kind of gradient as used in the plate. My approach here was to treat the cup like a blob of clay. The API contains powerful built-in transforms that I can later use to "stretch" the cup into shape. How cool is that?

import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.paint.Color;
import javafx.scene.shape.\*;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;

def plateGroup = Group {

translateX: 250
translateY: 300

 content: [

          // The gray ellipse under the plate
          Ellipse{centerX:0 centerY:10 radiusX:160 radiusY:50 fill:Color.DIMGRAY},

          // The thin "lip" of the plate (provides a sense of 3D)
          Ellipse{centerX:0 centerY:3  radiusX:170 radiusY:50 fill:Color.LAVENDER},

          // The large plate ellipse
          Ellipse{centerX:0 centerY:0  radiusX:170 radiusY:50
          fill:RadialGradient{
                    centerX:0.5 centerY:0.75
                    stops:[Stop {offset: 0.0 color: Color.WHITESMOKE},
                           Stop {offset: 0.5 color: Color.LIGHTGRAY},
                           Stop {offset: 1.0 color: Color.DARKGRAY}]
               }
          },

         // Recessed plate center
           Ellipse{centerX: 0 centerY: 5 radiusX: 90 radiusY: 22
                fill: RadialGradient{
                          centerX: 0.5 centerY: 0.75
                          stops:[Stop {offset: 0.0 color: Color.BLACK},
                                 Stop {offset: 0.4 color: Color.LIGHTGRAY},
                                 Stop {offset: 1.0 color: Color.GHOSTWHITE}]
                     }
          }
     ]
}

def cupGroup = Group {

     translateX: 152
     translateY: 20

     content: [
               // Cup body
               Circle {centerX: 100  centerY: 100 radius: 50
                    fill: RadialGradient {
                               centerX: 0.4 centerY: 0.0 focusX: 0.5 focusY: .65, proportional:true
                               stops: [Stop {offset: 0.0 color: Color.GHOSTWHITE},
                                       Stop {offset: 1.0 color: Color.SILVER}]
               }
          }
     ]
}


Stage {
    title: "Coffee Cup"
    visible: true
    scene: Scene {
         width: 500
         height: 500
         content: [plateGroup,cupGroup]
     }
}

To make this ball more "cup-like", I next placed a white rectangle over the top of the circle to flatten it out:

import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.paint.Color;
import javafx.scene.shape.\*;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;

def plateGroup = Group {

translateX: 250
translateY: 300

 content: [

          // The gray ellipse under the plate
          Ellipse{centerX:0 centerY:10 radiusX:160 radiusY:50 fill:Color.DIMGRAY},

          // The thin "lip" of the plate (provides a sense of 3D)
          Ellipse{centerX:0 centerY:3  radiusX:170 radiusY:50 fill:Color.LAVENDER},

          // The large plate ellipse
          Ellipse{centerX:0 centerY:0  radiusX:170 radiusY:50
          fill:RadialGradient{
                    centerX:0.5 centerY:0.75
                    stops:[Stop {offset: 0.0 color: Color.WHITESMOKE},
                           Stop {offset: 0.5 color: Color.LIGHTGRAY},
                           Stop {offset: 1.0 color: Color.DARKGRAY}]
               }
          },

         // Recessed plate center
           Ellipse{centerX: 0 centerY: 5 radiusX: 90 radiusY: 22
                fill: RadialGradient{
                          centerX: 0.5 centerY: 0.75
                          stops:[Stop {offset: 0.0 color: Color.BLACK},
                                 Stop {offset: 0.4 color: Color.LIGHTGRAY},
                                 Stop {offset: 1.0 color: Color.GHOSTWHITE}]
                     }
          }
     ]
}

def cupGroup = Group {

     translateX: 152
     translateY: 20

     content: [
               // Cup body
               Circle {centerX: 100  centerY: 100 radius: 50
                    fill: RadialGradient {
                               centerX: 0.4 centerY: 0.0 focusX: 0.5 focusY: .65, proportional:true
                               stops: [Stop {offset: 0.0 color: Color.GHOSTWHITE},
                                       Stop {offset: 1.0 color: Color.SILVER}]
               }
          },


               // Cut top of cup
               Rectangle{stroke: Color.WHITE fill: Color.WHITE 
                         x: 25 y: 50 width: 150 height: 50} 
     ]
}

Stage {
    title: "Coffee Cup"
    visible: true
    scene: Scene {
         width: 500
         height: 500
         content: [plateGroup,cupGroup]
     }
}

After that, I just added a couple more ellipses to make the outer and inner rims:

import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.paint.Color;
import javafx.scene.shape.\*;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;

def plateGroup = Group {

translateX: 250
translateY: 300

 content: [

          // The gray ellipse under the plate
          Ellipse{centerX:0 centerY:10 radiusX:160 radiusY:50 fill:Color.DIMGRAY},

          // The thin "lip" of the plate (provides a sense of 3D)
          Ellipse{centerX:0 centerY:3  radiusX:170 radiusY:50 fill:Color.LAVENDER},

          // The large plate ellipse
          Ellipse{centerX:0 centerY:0  radiusX:170 radiusY:50
          fill:RadialGradient{
                    centerX:0.5 centerY:0.75
                    stops:[Stop {offset: 0.0 color: Color.WHITESMOKE},
                           Stop {offset: 0.5 color: Color.LIGHTGRAY},
                           Stop {offset: 1.0 color: Color.DARKGRAY}]
               }
          },

         // Recessed plate center
           Ellipse{centerX: 0 centerY: 5 radiusX: 90 radiusY: 22
                fill: RadialGradient{
                          centerX: 0.5 centerY: 0.75
                          stops:[Stop {offset: 0.0 color: Color.BLACK},
                                 Stop {offset: 0.4 color: Color.LIGHTGRAY},
                                 Stop {offset: 1.0 color: Color.GHOSTWHITE}]
                     }
          }
     ]
}

def cupGroup = Group {

     translateX: 152
     translateY: 20

     content: [
               // Cup body
               Circle {centerX: 100  centerY: 100 radius: 50
                    fill: RadialGradient {
                               centerX: 0.4 centerY: 0.0 focusX: 0.5 focusY: .65, proportional:true
                               stops: [Stop {offset: 0.0 color: Color.GHOSTWHITE},
                                       Stop {offset: 1.0 color: Color.SILVER}]
               }
          },

               // Cut top of cup
               Rectangle{stroke: Color.WHITE fill: Color.WHITE 
                         x: 25 y: 50 width: 150 height: 50},

               // Outer rim
               Ellipse{fill: Color.WHITE centerX: 100 centerY: 100 radiusX: 50 radiusY: 8},

               // Inner rim
               Ellipse{centerX: 100 centerY: 100 radiusX: 48 radiusY: 7 //inner rim
                       fill: RadialGradient {
                                             centerX: 0.4 centerY: 0.0 focusX: 0.5 focusY:.4, proportional:true
                                             stops: [Stop {offset: 0.0 color: Color.GHOSTWHITE},
                                                     Stop {offset: 1.0 color: Color.SILVER}]
                       }
               }
     ]
}

Stage {
    title: "Coffee Cup"
    visible: true
    scene: Scene {
         width: 500
         height: 500
         content: [plateGroup,cupGroup]
     }
}

Things are looking good! But the cup is still too small. So to make the cup "grow", I just scaled the entire cup group upwards. I actually scaled the y axis slightly more, so as to squish the cup inwards a little to shape it more like an egg:

import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.paint.Color;
import javafx.scene.shape.\*;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;

def plateGroup = Group {

translateX: 250
translateY: 300

 content: [

          // The gray ellipse under the plate
          Ellipse{centerX:0 centerY:10 radiusX:160 radiusY:50 fill:Color.DIMGRAY},

          // The thin "lip" of the plate (provides a sense of 3D)
          Ellipse{centerX:0 centerY:3  radiusX:170 radiusY:50 fill:Color.LAVENDER},

          // The large plate ellipse
          Ellipse{centerX:0 centerY:0  radiusX:170 radiusY:50
          fill:RadialGradient{
                    centerX:0.5 centerY:0.75
                    stops:[Stop {offset: 0.0 color: Color.WHITESMOKE},
                           Stop {offset: 0.5 color: Color.LIGHTGRAY},
                           Stop {offset: 1.0 color: Color.DARKGRAY}]
               }
          },

         // Recessed plate center
           Ellipse{centerX: 0 centerY: 5 radiusX: 90 radiusY: 22
                fill: RadialGradient{
                          centerX: 0.5 centerY: 0.75
                          stops:[Stop {offset: 0.0 color: Color.BLACK},
                                 Stop {offset: 0.4 color: Color.LIGHTGRAY},
                                 Stop {offset: 1.0 color: Color.GHOSTWHITE}]
                     }
          }
     ]
}

def cupGroup = Group {

     translateX: 152
     translateY: 20
     scaleX: 3.0
     scaleY: 4.0

     content: [
               // Cup body
               Circle {centerX: 100  centerY: 100 radius: 50
                    fill: RadialGradient {
                               centerX: 0.4 centerY: 0.0 focusX: 0.5 focusY: .65, proportional:true
                               stops: [Stop {offset: 0.0 color: Color.GHOSTWHITE},
                                       Stop {offset: 1.0 color: Color.SILVER}]
               }
          },

               // Cut top of cup
               Rectangle{stroke: Color.WHITE fill: Color.WHITE 
                         x: 25 y: 50 width: 150 height: 50},

               // Outer rim
               Ellipse{fill: Color.WHITE centerX: 100 centerY: 100 radiusX: 50 radiusY: 8},

               // Inner rim
               Ellipse{centerX: 100 centerY: 100 radiusX: 48 radiusY: 7 //inner rim
                       fill: RadialGradient {
                                             centerX: 0.4 centerY: 0.0 focusX: 0.5 focusY:.4, proportional:true
                                             stops: [Stop {offset: 0.0 color: Color.GHOSTWHITE},
                                                     Stop {offset: 1.0 color: Color.SILVER}]
                       }
               },
     ]
}

Stage {
    title: "Coffee Cup"
    visible: true
    scene: Scene {
         width: 500
         height: 500
         content: [plateGroup,cupGroup]
     }
}

Filling the Cup

Now it's time to fill the cup! For this I made a custom shape from the intersection of the inner rim and a new coffee-colored ellipse. The built-in ShapeIntersect class makes this a trivial matter:

import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.paint.Color;
import javafx.scene.shape.\*;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;

def plateGroup = Group {

translateX: 250
translateY: 300

 content: [

          // The gray ellipse under the plate
          Ellipse{centerX:0 centerY:10 radiusX:160 radiusY:50 fill:Color.DIMGRAY},

          // The thin "lip" of the plate (provides a sense of 3D)
          Ellipse{centerX:0 centerY:3  radiusX:170 radiusY:50 fill:Color.LAVENDER},

          // The large plate ellipse
          Ellipse{centerX:0 centerY:0  radiusX:170 radiusY:50
          fill:RadialGradient{
                    centerX:0.5 centerY:0.75
                    stops:[Stop {offset: 0.0 color: Color.WHITESMOKE},
                           Stop {offset: 0.5 color: Color.LIGHTGRAY},
                           Stop {offset: 1.0 color: Color.DARKGRAY}]
               }
          },

         // Recessed plate center
           Ellipse{centerX: 0 centerY: 5 radiusX: 90 radiusY: 22
                fill: RadialGradient{
                          centerX: 0.5 centerY: 0.75
                          stops:[Stop {offset: 0.0 color: Color.BLACK},
                                 Stop {offset: 0.4 color: Color.LIGHTGRAY},
                                 Stop {offset: 1.0 color: Color.GHOSTWHITE}]
                     }
          }
     ]
}

def cupGroup = Group {

     translateX: 152
     translateY: 20
     scaleX: 3.0
     scaleY: 4.0

     content: [
               // Cup body
               Circle {centerX: 100  centerY: 100 radius: 50
                    fill: RadialGradient {
                               centerX: 0.4 centerY: 0.0 focusX: 0.5 focusY: .65, proportional:true
                               stops: [Stop {offset: 0.0 color: Color.GHOSTWHITE},
                                       Stop {offset: 1.0 color: Color.SILVER}]
               }
          },

          // Cut top of cup
          Rectangle{stroke: Color.WHITE fill: Color.WHITE 
                    x: 25 y: 50 width: 150 height: 50},

          // Outer rim
          Ellipse{fill: Color.WHITE centerX: 100 centerY: 100 radiusX: 50 radiusY: 8},

          // Inner rim
          Ellipse{centerX: 100 centerY: 100 radiusX: 48 radiusY: 7 //inner rim
                  fill: RadialGradient {
                                        centerX: 0.4 centerY: 0.0 focusX: 0.5 focusY:.4, proportional:true
                                        stops: [Stop {offset: 0.0 color: Color.GHOSTWHITE},
                                                Stop {offset: 1.0 color: Color.SILVER}]
                  }
          },
          
         // Create "coffee in cup" by intersecting coffee ellipse with inner rim ellipse
         ShapeIntersect {

              fill: Color.SADDLEBROWN

              //Inner Rim
              a: Ellipse{centerX:100 centerY:100 radiusX:48 radiusY:7} // inner rim dimensions

              //Coffee
              b: Ellipse{centerX:100 centerY:102 radiusX:46 radiusY:6} // coffee dimensions
         }
     ]
}

Stage {
    title: "Coffee Cup"
    visible: true
    scene: Scene {
         width: 500
         height: 500
         content: [plateGroup,cupGroup]
     }
}

And finally, I gave the whole thing a little extra class by setting the background to black:

import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.paint.Color;
import javafx.scene.Group;
import javafx.scene.paint.Color;
import javafx.scene.shape.\*;
import javafx.scene.paint.Stop;
import javafx.scene.paint.RadialGradient;

def BGCOLOR = Color.BLACK;

def plateGroup = Group {

     translateX: 250
     translateY: 300

     content: [

          // The gray ellipse under the plate
          Ellipse{centerX:0 centerY:10 radiusX:160 radiusY:50 fill:Color.DIMGRAY},

          // The thin "lip" of the plate (provides a sense of 3D)
          Ellipse{centerX:0 centerY:3  radiusX:170 radiusY:50 fill:Color.LAVENDER},

          // The large plate ellipse
          Ellipse{centerX:0 centerY:0  radiusX:170 radiusY:50
          fill:RadialGradient{
                    centerX:0.5 centerY:0.75
                    stops:[Stop {offset: 0.0 color: Color.WHITESMOKE},
                           Stop {offset: 0.5 color: Color.LIGHTGRAY},
                           Stop {offset: 1.0 color: Color.DARKGRAY}]
               } 
          },

          // Recessed plate center
           Ellipse{
                centerX:0 centerY:5 radiusX:90 radiusY:22
                fill:RadialGradient{
                          centerX:0.5 centerY:0.75
                          stops:[Stop {offset: 0.0 color: Color.BLACK},
                                 Stop {offset: 0.4 color: Color.LIGHTGRAY},
                                 Stop {offset: 1.0 color: Color.GHOSTWHITE}]
                     }
          }
     ] 
} 

def cupGroup = Group {
  
     translateX: 152
     translateY: 20
     scaleX: 3.0
     scaleY: 4.0

     content: [
               // Cup body
               Circle {centerX: 100  centerY: 100 radius: 50
                    fill: RadialGradient {
                               centerX: 0.4 centerY: 0.0 focusX: 0.5 focusY:.65, proportional:true
                               stops: [Stop {offset: 0.0 color: Color.GHOSTWHITE},
                                       Stop {offset: 1.0 color: Color.SILVER}]
                             }
                      },

               // Cut top of cup
               Rectangle{stroke: BGCOLOR fill: BGCOLOR
                         x:25 y:50 width:150 height:50},

               // Outer rim
               Ellipse{fill: Color.WHITE centerX:100 centerY:100 radiusX:50 radiusY:8},

               // Inner rim
               Ellipse{centerX:100 centerY:100 radiusX:48 radiusY:7 //inner rim
                       fill: RadialGradient {
                                             centerX: 0.4 centerY: 0.0 focusX: 0.5 focusY:.4, proportional:true
                                             stops: [Stop {offset: 0.0 color: Color.GHOSTWHITE},
                                                     Stop {offset: 1.0 color: Color.SILVER}]
                       }
               },

               // Create "coffee in cup" by intersecting coffee ellipse with inner rim ellipse
               ShapeIntersect {

                    fill:Color.SADDLEBROWN

                    //Inner Rim
                    a: Ellipse{centerX:100 centerY:100 radiusX:48 radiusY:7} // inner rim dimensions

                    //Coffee
                    b: Ellipse{centerX:100 centerY:102 radiusX:46 radiusY:6} // coffee dimensions
               }
     ]
}

Stage {
    title: "Coffee Cup"
    width: 500
    height: 500
    visible: true
    scene: Scene {
         fill: BGCOLOR
         content: [plateGroup,cupGroup]
     }
}

Conclusion and Future Steps

In conclusion, I found my first attempt at GUI programming with the 1.0 SDK to be quite successful, and ultimately a lot of fun. The declarative programming model is easy to use. Creating sophisticated visual effects becomes almost effortless. The most time-consuming part of the entire project was just tweaking the different gradient values to get the lighting the way I wanted. But the declarative nature of this language really made the actual programming a breeze. I'm really looking forward to what this language can do when it's placed into the hands of real graphic designers!

I'm stopping here because this is what I was able to accomplish in a single afternoon. From here the cup needs a handle and some extra decorations on its face. It would also be great to use key frame animation to add in a steam effect. If you're reading this and would like to add them in, feel free to post your solutions!

-- Scott Hommel

About

Blog about Java technology documentation.

Search

Categories
Archives
« April 2013
SunMonTueWedThuFriSat
 
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
    
       
Today