The Java Tutorials' Weblog
Deployment Toolkit 101
The Deployment Toolkit is a set of JavaScript functions that can help developers easily deploy rich internet applications. [Read More]Posted at 02:40PM Apr 02, 2009 by The Java Tutorial Team | Comments[7]
Converting Pre-JDK7 File I/O Code
Prior to JDK7, thejava.io.File class was the mechanism used for
file I/O, but it had several drawbacks. Perhaps you have legacy code that uses java.io.File
and would like to take advantage of the java.nio.file.Path functionality
with minimal impact on your code.[Read More]
Posted at 04:08PM Apr 01, 2009 by The Java Tutorial Team | Comments[3]
Deploying An Applet In Under 10 Minutes
Want to learn how to quickly deploy a Java applet?[Read More]Posted at 10:11PM Mar 31, 2009 by The Java Tutorial Team | Comments[17]
PathMatcher in NIO.2
In my last blog entry I show how to walk a file tree using aFileVisitor in a very simple Find example. Alan Bateman (the NIO.2 czar) suggested that, rather than use java.lang.String to match the file, I use the new PathMatcher API.
[Read More]
Posted at 06:28AM Mar 27, 2009 by The Java Tutorial Team | Comments[1]
Traversing a file tree in NIO.2
Have you downloaded JDK7 and played with NIO.2 yet? NIO.2 offers many new I/O features, particularly in the area of files and file system APIs. [Read More]Posted at 09:47AM Mar 24, 2009 by The Java Tutorial Team | Comments[3]
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
Posted at 07:43AM Feb 04, 2009 by The Java Tutorial Team | Comments[0]
NIO and JDK7
You may be familiar with the NIO (New I/O) api. This API, introduced in release 1.4, extended the previous I/O package and included support for pattern matching with Regular Expressions, Buffer support for primitive types, Character-set encoders and decoders, and Channels — an abstraction for devices capable of performing I/O operations (to name just some of the functionality).You may be familiar with NIO, but have you heard of NIO.2? NIO.2, part of the JDK7 effort, completes some of the work begun in the NIO api and goes much further: It includes an improved filesystem interface, multicast support, asynchronous I/O support, and complete socket-channel functionality (which was begun in release 1.4).
Thanks to OpenJDK, you can download and play with NIO.2 now. The NIO Project Page contains links to the latest binaries, javadoc, JSR 203, and links to bloggers involved in this effort.
-- Sharon Zakhour
Posted at 08:24AM Feb 02, 2009 by The Java Tutorial Team | Comments[2]
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
Posted at 09:36AM Jan 15, 2009 by The Java Tutorial Team | Comments[1]
JavaFX Rated as Top 10 for 2008
As you know, JavaFX 1.0 was released in early December and has been receiving some exciting attention among developers and the press. For example, eweek has ranked JavaFX as number 5 in its Top 10 Application Development Products for 2008.If you haven't yet checked it out, I would refer you to the last several entries on this blog. :)
Also, if you would like to run JavaFX applications and applets while not connected to the internet, check out this article by Thomas Ng.
Happy 2009!!
-- Sharon Zakhour
Posted at 11:27AM Jan 06, 2009 by The Java Tutorial Team | Comments[1]
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
Posted at 10:20AM Dec 12, 2008 by The Java Tutorial Team | Comments[21]
JavaFX on Facebook
Some folks at Sun have created the first JavaFX application to run on Facebook. If you have a Facebook account, please try it out! (And if you don't have a Facebook account, it's free.)The picture puzzle app runs on any browser supported by JavaFX, although you get more functionality if you are running JRE 6u10 or better.
To play with the jigsaw puzzle:
- Login to Facebook.
- Search on JavaFX and from the results select JavaFXPicturePuzzle — it should be the second item listed. (It's located at http://apps.facebook.com/javafxpicturepuzzle/Puzzle.)
- Select Go to Application and accept the security questions when prompted.
- Bookmark the app so that you can easily find it again — the Bookmark JavaFXPicturePuzzle button is at the bottom of the page.
- Please share with your friends by selecting the Share with Friends tab near the top of the page.
Let us know what you think!
-- Sharon Zakhour
Posted at 10:40AM Dec 09, 2008 by The Java Tutorial Team | Comments[6]
JavaFX is here!!
Released late last week, JavaFX 1.0 is here!!!My team created two of the tutorials for JavaFX:
Please check it out and let us know what you think!
Sharon Zakhour
Posted at 12:54PM Dec 08, 2008 by The Java Tutorial Team | Comments[2]
Sun in Second Life
Have you tried Second Life yet? Probably you have at least heard of this internet-based virtual reality game, though you might have heard about its more salacious side. And yes, that does exist.
But Second Life is far more than that. It's an enormous and varied community — a rich place for people and activities of all sorts to interact and explore.
And did you know that Sun Microsystems has a presence in Second Life? Sun has three public sims and hosts a variety of events, such as the events held on our new Solaris campus.
How do you find us? You can search Places within SL, but here are Sun's Second Life URLS (SLURLs). You can click these links in your browser and they will launch Second Life (or open a Teleport window within the app):
Sun is hosting a Halloween party at Club Java on October 31st, 8am SLT. (Second Life Time is equivalent to Pacific time.) There will be a costume contest with a $1000L prize for best costume (Linden dollars are the currency used in SL.) There will also be a live DJ.Above my avatar is modeling the costume I prepared for the event. (The Headless HUD with facial expressions is available from Tortec.)
At some point, we may host a tutorial related event in Second Life. Would you find that interesting? Sun hosts other talks and events on its public sims. There are also freebies, such as t-shirts, backpacks, etc. (Of the virtual variety, of course.)
If you haven't yet tried Second Life, here is a good opportunity. You only need download the application from secondlife.com, create a new account on the website, log in and voila — it's completely free.
I hope to see you at the Halloween party!
-- Sharon Zakhour
Posted at 04:40AM Oct 31, 2008 by The Java Tutorial Team | Comments[4]
Link to the Latest API Specification in Japanese
Last week I posted about the new link that will always point to the latest API specification: http://java.sun.com/javase/current/docs/api/index.html.We received feedback from Manabu Nakamura asking us to provide the same link for the Japanese translation.
Ask and you shall receive.
It has gone live today: http://java.sun.com/javase/current/ja/docs/ja/index.html.
Thanks for the great idea, Manabu!!
-- Sharon Zakhour
Posted at 07:56AM Sep 24, 2008 by The Java Tutorial Team | Comments[2]
Link to the Latest API Specification
Up until now, if you wanted to view the Java API, you had to specify a particular release of the JDK. For example:- JDK 6 — http://java.sun.com/javase/6/docs/api/index.html
- JDK 5 — http://java.sun.com/j2se/1.5.0/docs/api/
We are introducing a new link that will always take you to the latest API specification. If you create a link to (or bookmark) this new URL, you are guaranteed to always be linked to the latest documentation. Currently it links to the JDK 6 API spec, but it will take you to the JDK 7 API spec when it is released.
We hope you find this to be handy!
-- Sharon Zakhour
Posted at 11:22AM Sep 18, 2008 by The Java Tutorial Team | Comments[8]
Thursday Apr 02, 2009