The Java Tutorials' Weblog
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
Posted at 08:06AM Nov 17, 2009 by The Java Tutorial Team | Comments[5]
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
Posted at 02:26PM Sep 09, 2009 by The Java Tutorial Team | Comments[3]
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 a> 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
Posted at 10:09AM May 27, 2009 by The Java Tutorial Team | Comments[7]
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]
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 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]
Changing the java.ext.dirs Property
We received a question on the java tutorials alias that isn't covered in the Extension Mechanism tutorial. We were asked if there is a way to set theext path using an environment variable. Something along the lines of:
export JAVA_EXT_PATH="/opt/MyProduct/java-ext"
No, there is no environment variable, but there is the java.ext.dirs system property. For example:
java -Djava.ext.dirs=/foo/bar/baz:/bleem/grumpf MyApp
See the Extension
Mechanism Architecture spec
and search for "java.ext.dirs" and you can read a bit more. In particular, note that the path separator (':' above) is platform dependent, so it would be a semi colon on Windows.
Thanks to Maxim Vexler for asking the question and especially to Dave Bristor in software for answering it. :-)
-- Sharon Zakhour
Posted at 02:45PM Sep 02, 2008 by The Java Tutorial Team | Comments[0]
Changing the Java Web Start Splash Screen
Java applications that are launched with Java Web Start have a default splash screen that displays before your application is ready to run on your system. For JavaSE 6 Update 10, this splash screen looks like the following:

You can change this splash image to one with your own GIF, JPG, or PNG file. The first time Java Web Start launches your application you will see the default Java cup logo image. All subsequent launches will display your splash image.
Java Network Launch Protocol (JNLP)
All applications launched with Java Web Start technology have an associated
JNLP file (a file name with a .jnlp extension). You need to edit
this JNLP file and specify the image you want to use for your splash screen.
Essentially, you add one line to the <information>
element within your JNLP file:
<icon href="mysplash.jpg" kind="splash"/>
where the mysplash.jpg file is the image file you want to use
to replace the default splash image.
Note: For more information about JNLP, refer to the Java Web Start Developers Guide or the JNLP specification.
Here is an example JNLP file with this <icon> line added
to the <information> element:
<?xml version="1.0" encoding="utf-8"?>
<!-- JNLP File for ButtonDemo -->
<jnlp
spec="1.0+" codebase="http://java.sun.com/docs/books/tutorialJWS/uiswing/components" href="ButtonDemo.jnlp"> <information><title>ButtonDemo</title> <vendor>The Java(tm) Tutorial: Sun Microsystems, Inc.</vendor> <homepage href="http://java.sun.com/docs/books/tutorial/uiswing/examples/components/index.html#ButtonDemo"/> <icon href="mysplash.jpg" kind="splash"/> <description>ButtonDemo</description> <description kind="short">Demonstrates use of buttons within containers</description> <offline-allowed/></information> <resources><j2se version="1.6+"/> <jar href="ButtonDemo.jar"/></resources> <application-desc main-class="components.ButtonDemo"/>
</jnlp>
The JAR file with your application is stored on the web server in a location
specified by the codebase value in the JNLP file. The path you
specify for your splash image is relative to the codebase value.
So for example, in the JNLP file above, the file mysplash.jpg needs
to be stored in the directory specified by the codebase.
Try It Out
To see this in action, try this Java
programming language ButtonDemo. When you first launch it with Java Web
Start technology, the default Java cup logo splash screen displays on your screen
before the application appears on your desktop. When you launch the application
a second time, the image for the file mysplash.jpg will display
before the ButtonDemo application appears on your desktop.
-- Debra Scott
Posted at 03:31PM Aug 12, 2008 by The Java Tutorial Team | Comments[7]
JavaFX Preview SDK is now LIVE!
"JavaFX is a family of products for creating rich internet applications (RIA) with immersive media and content, across all the screens of your life. It includes a runtime and a tools suite that web scripters, designers and developers can use to quickly build and deliver the next generation of rich interactive applications for desktop, mobile devices, TV, and other platforms."
http://javafx.com
http://java.sun.com/javafx
https://openjfx.dev.java.net
http://blogs.sun.com/javafx
Posted at 08:56AM Jul 31, 2008 by The Java Tutorial Team | Comments[0]
Thumbnail Tooltip Demo
Frequent contributor to the tutorial forum, Collin Fagan, has created a new demo that combines bits of other tutorial demos plus some interesting new functionality.ThumbnailTooltipDemo features a tabbed pane containing three tabs. The first tab shows a tree, the second a table, and the third contains a grid of images. What's interesting here is that when you hover the mouse over one of the tabs, you see a pictorial tooltip representing the contents of that tab. The tooltip is dynamically generated, so if the appearance of the pane changes, by highlighting text, for example, that change is reflected in the tooltip.
You can see the forum thread or check out the wiki page with the source code.
Very cool, Collin!
-- Sharon Zakhour
Posted at 11:29PM Jun 19, 2008 by The Java Tutorial Team | Comments[0]
1.4 Version of the Java Tutorials
Some of you don't have the luxury of using the newer releases of the JDK and we are occasionally asked for an older version -- particularly release 1.4 of the JDK. Before we moved to the Sun Download Center, we did have a page that contained some, but not all, of the older versions of the tutorial.I went to my pile of old published tutorials and extracted the 1.4 version from the cd included with the Second Edition of The Swing Tutorial. I've made it available through the Java Tutorials Community Portal: tutorial_1.4.zip.
Enjoy!
-- Sharon Zakhour
Posted at 11:34AM Jun 04, 2008 by The Java Tutorial Team | Comments[0]
Preparing for Java Programming Language Certification
When we updated the core Java Tutorial to JDK 6, we included a page designed to help those who are studying for Java Programming Language Certification. This study guide calls out which portions of the tutorial are relevant to the testing objectives -- it is by no means comprehensive. Nor does it discuss the test and what to expect.We still sometimes receive questions on the tutorial feedback alias asking how to prepare for the Java Programmer Certification test. The book strongly recommended by our Java instructors and course developers is the Complete Java 2 Certification Study Guide by Philip Heller.
You can follow this thread on the Java Tutorials Community forum.
-- Sharon Zakhour
Posted at 07:48AM May 20, 2008 by The Java Tutorial Team | Comments[4]
DefaultTreeModel -- Adding, Removing and Updating Nodes
Many moons ago I had a discussion with Collin Fagan (Java Tutorial contributor and all around helpful guy) about the fact that I had seen some requests for a tutorial on how to add, remove and update nodes in a DefaultTreeModel.Collin wasted no time creating such an example. Unfortunately, resources being what they are, I wasn't able to get engineering cycles for reviewing the example. Because we generally don't include material that hasn't been reviewed by engineering, it was backburnered.
Meanwhile, Collin posted his example and some accompanying text, The Secret Life of a DefaultTreeModel on JavaLobby.
Collin has now posted his example on the JavaTutorials forum!
When you compile and run the example (it will run under JDK 5) it brings up a panel containing a tree with a root node. When you open the root node you'll see three child nodes. At this point you can right-click any of the nodes (control-click on a Mac) and you can add 50 children to the current selection, remove the current selection, or modify the text on the current selection.
Thanks for this very useful example, Collin!
-- Sharon Zakhour
Posted at 02:46PM May 16, 2008 by The Java Tutorial Team | Comments[0]
Tuesday Nov 17, 2009