Frosted Glass Effect in JavaFX? - java

I'm making an iOS7-themed JavaFX2/FXML project and I was wondering how I could make a Rectangle object have a iOS7-like frosted glass effect.
I'd also like it to have a small shadow. This is tricky, since you might be able to see the shadow behind the semi-transparent object. I'd just like it to be present around the edges.
Is this possible? Here's a picture showing the desired effect (not including the small drop-shadow):
UPDATE: Here's a continuation of the issue. This is going to look amazing :D.

Sample Solution
Run the program below and scroll or swipe up to show the glass pane.
The purpose of the program is just to sample the techniques involved not to act as a general purpose library for the frost effect.
import javafx.animation.*;
import javafx.application.Application;
import javafx.beans.property.*;
import javafx.geometry.Rectangle2D;
import javafx.scene.*;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.effect.*;
import javafx.scene.image.*;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
// slides a frost pane in on scroll or swipe up; slides it out on scroll or swipe down.
public class Frosty extends Application {
private static final double W = 330;
private static final double H = 590;
private static final double BLUR_AMOUNT = 60;
private static final Duration SLIDE_DURATION = Duration.seconds(0.4);
private static final double UPPER_SLIDE_POSITION = 100;
private static final Effect frostEffect =
new BoxBlur(BLUR_AMOUNT, BLUR_AMOUNT, 3);
#Override public void start(Stage stage) {
DoubleProperty y = new SimpleDoubleProperty(H);
Node background = createBackground();
Node frost = freeze(background, y);
Node content = createContent();
content.setVisible(false);
Scene scene = new Scene(
new StackPane(
background,
frost,
content
)
);
stage.setScene(scene);
stage.show();
addSlideHandlers(y, content, scene);
}
// create a background node to be frozen over.
private Node createBackground() {
Image backgroundImage = new Image(
getClass().getResourceAsStream("ios-screenshot.png")
);
ImageView background = new ImageView(backgroundImage);
Rectangle2D viewport = new Rectangle2D(0, 0, W, H);
background.setViewport(viewport);
return background;
}
// create some content to be displayed on top of the frozen glass panel.
private Label createContent() {
Label label = new Label("The overlaid text is clear and the background below is frosty.");
label.setStyle("-fx-font-size: 25px; -fx-text-fill: midnightblue;");
label.setEffect(new Glow());
label.setMaxWidth(W - 20);
label.setWrapText(true);
return label;
}
// add handlers to slide the glass panel in and out.
private void addSlideHandlers(DoubleProperty y, Node content, Scene scene) {
Timeline slideIn = new Timeline(
new KeyFrame(
SLIDE_DURATION,
new KeyValue(
y,
UPPER_SLIDE_POSITION
)
)
);
slideIn.setOnFinished(e -> content.setVisible(true));
Timeline slideOut = new Timeline(
new KeyFrame(
SLIDE_DURATION,
new KeyValue(
y,
H
)
)
);
scene.setOnSwipeUp(e -> {
slideOut.stop();
slideIn.play();
});
scene.setOnSwipeDown(e -> {
slideIn.stop();
slideOut.play();
content.setVisible(false);
});
// scroll handler isn't necessary if you have a touch screen.
scene.setOnScroll((ScrollEvent e) -> {
if (e.getDeltaY() < 0) {
slideOut.stop();
slideIn.play();
} else {
slideIn.stop();
slideOut.play();
content.setVisible(false);
}
});
}
// create a frosty pane from a background node.
private StackPane freeze(Node background, DoubleProperty y) {
Image frostImage = background.snapshot(
new SnapshotParameters(),
null
);
ImageView frost = new ImageView(frostImage);
Rectangle filler = new Rectangle(0, 0, W, H);
filler.setFill(Color.AZURE);
Pane frostPane = new Pane(frost);
frostPane.setEffect(frostEffect);
StackPane frostView = new StackPane(
filler,
frostPane
);
Rectangle clipShape = new Rectangle(0, y.get(), W, H);
frostView.setClip(clipShape);
clipShape.yProperty().bind(y);
return frostView;
}
public static void main(String[] args) { launch(args); }
}
Source image
Save this image parallel to the Java source as a file named ios-screenshot.png and have your build system copy it to the target directory for the binary output of the build.
Answers to additional questions
"JDK 8," would that happen to be a requirement of this?
The sample code above is written against JDK 8. Porting it back to JDK 7 by replacing the lambda calls with anonymous inner classes is pretty trivial.
In general, Java 7 is pretty dated for JavaFX work. I advise upgrading at your earliest convenience to work with a Java 8 minimum version.
initiating your Panes with arguments
More convenient constructors for most parent nodes is a Java 8 feature. You can easily convert the Java 8 format:
StackPane stack = new StackPane(child1, child2);
To Java 7:
StackPane stack = new StackPane();
stack.getChildren().setAll(child1, child2);
will this working if the desktop is behind a frosty pane?
Not directly, you can create a new question for that.
Update: Related Questions
User created: JavaFX effect on background to allow the frosted effect to apply to a window over a desktop background.
Another user created: How do I create a JavaFX transparent stage with shadows on only the border? to apply a halo shadow effect around this window.

Related

UI Popup Opacity Mask JavaFX

Is it possible with Popup opacity mask top and bottom JavaFX? I have TextField autocomplete with Popup. So the idea is to put an opacity mask.
Below is another way you can give a try, for getting the opacity masked effect. Though it is not exactly the same implementation, I took some ideas from the link you provided :).
I created a small utility where you can pass the Popup instance. The utility builds the mask panes and include to the root node of the Popup.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.stage.Popup;
import javafx.stage.Stage;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class PopupOpacityMaskDemo extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
StackPane root = new StackPane();
root.setStyle("-fx-background-color:grey;");
root.setOnMouseClicked(e -> {
ListView<String> content = new ListView<>();
content.getItems().addAll(IntStream.range(100, 200).mapToObj(i -> i + "").collect(Collectors.toList()));
content.setPrefSize(200, 250);
Popup popup = new Popup();
popup.setAutoHide(true);
popup.getContent().add(content);
popup.setX(e.getScreenX());
popup.setY(e.getScreenY());
popup.show(root.getScene().getWindow());
MaskUtil.applyMask(popup);
});
Scene scene = new Scene(root, 200, 200);
primaryStage.setScene(scene);
primaryStage.setTitle("Demo");
primaryStage.show();
}
static class MaskUtil{
static void applyMask(Popup popup) {
double fadeSize = 70;
Pane pane = (Pane)popup.getScene().getRoot();
// Build the mask panes
Pane topMask = buildMaskPane(pane, fadeSize, false);
Pane bottomMask = buildMaskPane(pane, fadeSize, true);
// Just ensuring to remove any masks (if you are reusing the Popup)
pane.getChildren().removeAll(pane.lookupAll(".mask"));
pane.getChildren().addAll(topMask, bottomMask);
// Update the bottom mask position by listening to height of pane
pane.heightProperty().addListener((obs, old, h) -> bottomMask.setLayoutY(h.doubleValue() - fadeSize));
if (pane.getHeight() > 0) {
bottomMask.setLayoutY(pane.getHeight() - fadeSize);
}
}
private static Pane buildMaskPane(Pane pane, double fadeSize, boolean isBottom) {
Pane mask = new Pane();
mask.setMouseTransparent(true); // Turn this to 'false' if you don't want to interact over mask
mask.setPrefHeight(fadeSize);
mask.prefWidthProperty().bind(pane.widthProperty());
mask.maxHeightProperty().bind(mask.prefHeightProperty());
mask.minHeightProperty().bind(mask.prefHeightProperty());
mask.getStyleClass().add("mask");
mask.setStyle(String.format("-fx-background-color:linear-gradient(to %s, #555555, transparent)", isBottom ? "top" : "bottom"));
return mask;
}
}
}

JavaFX- Rotating my cube moves it off camera, how do I prevent this from happening?

I just started learning 3D graphics with javaFX not too long ago, I am currently working on rotating the model. While it does rotate, the way that it rotates is not exactly what I had in mind...For example if I press the key to rotate left the model moves towards the left hand side of the screen while it is rotating and eventually goes off screen.
Here's some of the code to construct the box and scene:
Box box = new Box(100,20,50);
SmartGroup group = new SmartGroup();
group.getChildren().add(box);
Camera camera = new PerspectiveCamera();
Scene scene = new Scene(group,WIDTH,HEIGHT);
scene.setFill(Color.SILVER);
scene.setCamera(camera);
box.translateXProperty().set(WIDTH/2);
box.translateYProperty().set(HEIGHT/2);
box.translateZProperty().set(-1000);
//Here's the wrapper class I made to make the box move:
class SmartGroup extends Group{
Rotate r;
Transform t = new Rotate();
void rotateByX(double ang){
r = new Rotate(ang, Rotate.X_AXIS);
t = t.createConcatenation(r);
this.getTransforms().clear();
this.getTransforms().addAll(t);
}
void rotateByY(double ang){
r = new Rotate(ang, Rotate.Y_AXIS);
t = t.createConcatenation(r);
this.getTransforms().clear();
this.getTransforms().addAll(t);
}
void rotateByZ(double ang){
r = new Rotate(ang, Rotate.Z_AXIS);
t = t.createConcatenation(r);
this.getTransforms().clear();
this.getTransforms().addAll(t);
}
}
So basically my model is rotating but also moving off screen. I want it to stay in place and rotate on a set axis. How would I go about doing
Here is an example which rotates a box about the Y axis.
The example uses a RotateTransition for the rotation.
The rotate transition is applied on the box being rotated, not an enclosing group.
There are other ways to achieve rotation, for instance you could manually create transforms and apply them in an animation timer or a timeline.
Generally, if you are trying to rotate something in 3D and it is not rotating about its center but instead some distant origin point, it will look like it is moving away or toward from the camera, because it is not rotating around its center but, instead, around somewhere else.
To fix that, what you can do is apply a series of transforms, one to translate the object to an origin point (0,0,0) then a second to actually rotate the object, and finally a third to translate the rotated object back to the position it was in before. A similar technique can be applied to scale an object as well.
I didn't do all that because I could just make use of the higher level RotateTransition to rotate the object about a Y axis running through the object's center. The RotateTransition takes care of all the necessary transforms for you, so that you don't need to worry about formulating and applying them. However, in some other use model, the alternate approach using multiple transforms could be used.
import javafx.animation.Interpolator;
import javafx.animation.RotateTransition;
import javafx.animation.Transition;
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;
import javafx.util.Duration;
public class RotatingBoxApp extends Application {
public Parent createContent() {
// Box
Box testBox = new Box(5, 5, 5);
testBox.setMaterial(new PhongMaterial(Color.LIMEGREEN));
// Create and position camera
PerspectiveCamera camera = new PerspectiveCamera(true);
camera.getTransforms().addAll(
new Rotate(-20, Rotate.Y_AXIS),
new Rotate(-20, Rotate.X_AXIS),
new Translate(0, 0, -20)
);
// Build the Scene Graph
Group root = new Group();
root.getChildren().add(camera);
root.getChildren().add(testBox);
RotateTransition rotator = new RotateTransition(Duration.seconds(5), testBox);
rotator.setAxis(Rotate.Y_AXIS);
rotator.setFromAngle(0);
rotator.setToAngle(360);
rotator.setCycleCount(Transition.INDEFINITE);
rotator.setInterpolator(Interpolator.LINEAR);
rotator.play();
// Use a SubScene
SubScene subScene = new SubScene(root, 300, 300);
subScene.setFill(Color.web("#4a4f59"));
subScene.setCamera(camera);
Group group = new Group();
group.getChildren().add(subScene);
return group;
}
#Override
public void start(Stage primaryStage) {
primaryStage.setResizable(false);
Scene scene = new Scene(createContent());
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
In general if you want further help with issues like this, you usually need to provide an mcve (minimal code which somebody could copy and paste to run unchanged and reproduce the issue). Without an mcve, you will tend to get less help. For example, from the code you supplied, I couldn't really tell you exactly what you are doing wrong in your implementation.

How to position a JavaFX context menu inside the main window?

Hi I am a JavaFX newbie and I am trying to write my first application. I want to start with an empty window and provide a popup menu that allows users to add 3D elements to the window.
I have created a simple Group containing a few trivial geometric shapes and added this group as the parent to a Scene. I define a mouse event handler for the scene and call setScene to make this the scene for my Stage (passed in to my Application's start method).
Unfortunately, I can't seem to find a way of positioning the menu correctly in response to a mouse pressed event. I get it that I need to get the X and Y coordinates from the Event, but when I pass these unchanged to the context menu show method, the menu appears in the top left-hand corner of my laptop display, rather than inside my application window.
Clearly, I need to offset these values by the origin of some other window, but what? I have tried the Scene, the Group and and the Stage, but with no success :-( This ought to be a trivial problem - where am I going wrong??
Code sample shown below:
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.PointLight;
import javafx.scene.Scene;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.shape.Box;
import javafx.scene.shape.Cylinder;
import javafx.scene.shape.Sphere;
import javafx.stage.Stage;
public class PopupTest extends Application {
private static final ContextMenu contextMenu = new ContextMenu();
public static void main(String[] args) {
MenuItem cut = new MenuItem("Cut");
MenuItem copy = new MenuItem("Copy");
MenuItem paste = new MenuItem("Paste");
contextMenu.getItems().addAll(cut, copy, paste);
Application.launch(args);
}
#Override
public void start(Stage stage) {
// Create a Box
Box box = new Box(100, 100, 100);
box.setTranslateX(150);
box.setTranslateY(0);
box.setTranslateZ(400);
// Create a Sphere
Sphere sphere = new Sphere(50);
sphere.setTranslateX(300);
sphere.setTranslateY(-5);
sphere.setTranslateZ(400);
// Create a Cylinder
Cylinder cylinder = new Cylinder(40, 120);
cylinder.setTranslateX(500);
cylinder.setTranslateY(-25);
cylinder.setTranslateZ(600);
// Create a Light
PointLight light = new PointLight(Color.YELLOW);
light.setTranslateX(350);
light.setTranslateY(100);
light.setTranslateZ(300);
// Create a Camera to view the 3D Shapes
PerspectiveCamera camera = new PerspectiveCamera(false);
camera.setTranslateX(100);
camera.setTranslateY(-50);
camera.setTranslateZ(300);
// Add the Shapes and the Light to the Group
Group root = new Group(box, sphere, cylinder, light);
// Create a Scene with depth buffer enabled
Scene scene = new Scene(root, 400, 300, true);
scene.setOnMousePressed(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
System.out.println("mouse click detected!");
if (event.isPopupTrigger()) {
// similar results with getX() vs getSceneX() etc.
System.out.println("Display menu at (" + event.getSceneX() + "," + event.getSceneY() + ")");
contextMenu.show(root, event.getSceneX(), event.getSceneY());
}
}
});
// Add the Camera to the Scene
scene.setCamera(camera);
// Add the Scene to the Stage
stage.setScene(scene);
// Set the Title of the Stage
stage.setTitle("Trying to get popup menu working");
// Display the Stage
stage.show();
}
}

JavaFx Canvas only resizes in height but not in width

I have started programming this app for ploting temperature data, when the screen gets resized, the canvas should resize as well. It initializes correctly but when I want to resize the window, the draw() method will only resize the height, according to the stackpanes height value it is bound to but it will ignore the width entirely. The Listener won't even fire. This I find very strange. Also I have to set the minSize for the StackPane, otherwise nothing will be draw at all. I'm not using FXML.
Does anybody have any ideas?
Edit I changed line 58 from setRight() to setCenter, as mentioned in the solution from InternetUnexplorer. But I was still curious about why it is so, so I did some research. I found this in the internet:
Top/Bottom area: Can shrink/expand horizontally and keep the height
unchanged.
Left/Right area: Can shrink/expand vertically and keep the length
unchanged.
Center area: Can shrink/expand in both directions.
http://o7planning.org/en/10629/javafx-borderpane-layout-tutorial
Here my main class:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class main extends Application {
#Override
public void start(Stage mainStage) throws Exception {
TempViewerWindow view = new TempViewerWindow();
ReadData controller = new ReadData(view);
controller.selectAll();
mainStage.setScene(new Scene(view));
//mainStage.setMinWidth(500);
//mainStage.setMinHeight(400);
mainStage.setTitle("Temperature Viewer");
mainStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
And here my view class:
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
public class TempViewerWindow extends BorderPane {
public TableView<TempData> tableView;
public Canvas canvas;
public GraphicsContext gc;
public StackPane holder;
public TempViewerWindow() {
tableView = new TableView<>();
TableColumn<TempData, String> col_date = new TableColumn<>("Date");
TableColumn<TempData, Float> col_temperature = new TableColumn<>("Temperature");
col_date.setCellValueFactory(e -> e.getValue()
.dateProperty());
col_temperature.setCellValueFactory(e -> e.getValue()
.temperatureProperty()
.asObject());
tableView.getColumns()
.addAll(col_date, col_temperature);
setLeft(tableView);
holder = new StackPane();
holder.setMinSize(400, 400); // must be here for some reason
canvas = new Canvas();
gc = canvas.getGraphicsContext2D();
canvas.widthProperty()
.bind(holder.widthProperty()
.subtract(10));
canvas.heightProperty()
.bind(holder.heightProperty()
.subtract(10));
canvas.widthProperty()
.addListener(observable -> redraw(gc));
canvas.heightProperty()
.addListener(observable -> redraw(gc));
holder.getChildren()
.add(canvas);
setCenter(holder); //here was the bug
}
private void redraw(GraphicsContext gc) {
gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
gc.setFill(Color.WHITE);
gc.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
System.out.println("redraw!");
}
}
Your canvas is being placed in the right of your BorderPane, when you should be placing it in the center.
If you change line 54 of TempViewerWindow from setRight(holder) to setCenter(holder), the scaling works properly.
You're using a BorderPane as parent for holder. The holder is used as right child of the BorderPane. However the right/left children are resized to their preferred widths and are resized to fill the height between the top and bottom nodes. (See javadoc)
The left and right children will be resized to their preferred widths and extend the length between the top and bottom nodes.
If you'd use holder as center, it's width would be adjusted the way you expect it.
Alternatively you could use a HBox as base class for TempViewerWindow to achieve this kind of behavior.
public TempViewerWindow() {
...
this.getChildren().addAll(tableView, holder);
HBox.setHgrow(holder, Priority.ALWAYS);
HBox.setHgrow(tableView, Priority.NEVER);
this.setFillHeight(true);
}

JavaFx8 VBox center image

I have a JavaFx VBox inside of a ScrollPane:
VBox container = new VBox();
container.setAlignment(Pos.CENTER);
...
scrollPane.setContent(container);
scrollPane.setFitToWidth(true);
scrollPane.setHbarPolicy(ScrollBarPolicy.NEVER);
scrollPane.setVbarPolicy(ScrollBarPolicy.NEVER);
scrollPane.setMinWidth(150);
scrollPane.setPannable(true);
the size of this VBox never change, inside i have some labels, one label has an user image
like the next image(A)
the image is resized to some Height, but i don't know the size of this image, so if the width of the image is bigger than width of the VBox, this happen(part of the image hidden)(B)
but i don't want this, i want something like the following image:(the sides of the image hidden if the image width is bigger than the VBox width)(C)
http://i.stack.imgur.com/B3DOK.png
How i can do this?
I tried to put a rectangle as clip, in this rectangle i wanna show the center of the image, but the same happens.
imageView.setClip(new Rectangle(centerX - recSize, centerY - recSize, recSize*2, recSize*2));
---------------with the clip----------------
red = original image
blue = part of the image that is visible
http://i.stack.imgur.com/mYbyF.png
Nice(D)
Not nice:(E)(labels not centered correctly because of the image.)
Sorry by the links, i can't put the images directly
Solution
Set a viewport on the image not a clip.
imageView.setViewport(
new Rectangle2D(500, 320, 420, 300)
);
Sample
Here is a sample. It's not going to exactly match what you are asking for because even with the linked images in your question, I can't quite understand what you are trying to do. But I think it should give you enough background info that you can learn to accomplish what you want.
The sample creates an image view as a graphic in a scroll pane. The image view applies a viewport to the image and scales the viewport with preserved ratio. This allows a scaled portion of the much larger image to be displayed. It's kind of like a thumbnail clip (click on the thumbnail to display the full image).
import javafx.application.Application;
import javafx.geometry.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.effect.*;
import javafx.scene.image.*;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.*;
import javafx.stage.*;
// display a captioned image in a viewport.
// click the image to get an expanded view.
public class LabelWithImage extends Application {
private static final double IMAGE_WIDTH = 150;
#Override
public void start(Stage stage) {
Image image = new Image(IMAGE_LOC);
ImageView imageView = new ImageView(
image
);
imageView.setViewport(
new Rectangle2D(500, 320, 420, 300)
);
imageView.setFitWidth(IMAGE_WIDTH);
imageView.setPreserveRatio(true);
Label labeledImage = createCaptionedImage(
imageView,
"Village Home"
);
addGlowOnMouseOver(labeledImage);
labeledImage.setOnMouseClicked(event -> {
displayFullImage(stage, image);
});
VBox vbox = new VBox( // vbox just there to mimic question askers structure.
labeledImage
);
vbox.setPadding(new Insets(10));
ScrollPane scrollPane = makeScrollable(vbox);
Scene scene = new Scene(
scrollPane
);
stage.setScene(scene);
stage.show();
stage.setMaxWidth(stage.getWidth());
stage.setMaxHeight(stage.getHeight());
}
private void displayFullImage(Stage stage, Image image) {
Stage displayStage = new Stage();
displayStage.initStyle(StageStyle.UTILITY);
displayStage.initModality(Modality.APPLICATION_MODAL);
displayStage.initOwner(stage);
displayStage.setScene(
new Scene(
new Group(
new ImageView(
image
)
)
)
);
displayStage.show();
}
private void addGlowOnMouseOver(Node node) {
Glow glow = new Glow();
DropShadow shadow = new DropShadow(20, Color.GOLD);
glow.setInput(shadow);
node.setOnMousePressed(event -> node.setEffect(null));
node.setOnMouseEntered(event -> node.setEffect(glow));
node.setOnMouseExited(event -> node.setEffect(null));
}
private ScrollPane makeScrollable(Node node) {
ScrollPane scrollPane = new ScrollPane(node);
scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
scrollPane.setPannable(true);
return scrollPane;
}
private Label createCaptionedImage(ImageView imageView, String caption) {
Label labeledImage = new Label(caption);
labeledImage.setFont(Font.font("Athelas", FontPosture.ITALIC, 20));
labeledImage.setStyle("-fx-background-color: cornsilk");
labeledImage.setPadding(new Insets(0, 0, 5, 0));
labeledImage.setGraphic(
imageView
);
labeledImage.setContentDisplay(ContentDisplay.TOP);
return labeledImage;
}
public static void main(String[] args) {
launch(args);
}
private static final String IMAGE_LOC =
"http://www.imgion.com/images/01/beautiful-village-home.jpg";
// image courtesy of http://www.imgion.com which provides
// "free images on large topics to share with your friends and on your blogs."
}

Categories