How-To's > How do I work with images?


You can choose from two main ways to bring images in from outside your JavaFX application. Select the topic that most closely matches your interest.

See Also

How do I load and display images?


Use the Image class in the package javafx.scene.image to to load images that are in JPG, GIF, or PNG format. Use the ImageView class to display the loaded images. The ImageView class inherits from the Node class, enabling animations and effects such as drop shadow, glow, and reflection to be applied to images.

Images can be loaded from a URL or from a location within your application source. You can optionally load the image in the background, and you can display a placeholder image while the larger image is loading.

Example Code

The following code shows how to load a large image in the background while displaying a placeholder image. The main image is loaded from a URL, and the placeholder image is loaded from a local directory internal to the application.

import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;

def image = Image {
    url: "http://site.example.com/JavaFX/image1.jpg"
    backgroundLoading: true
    placeholder: Image {
        url: "{__DIR__}res/image2.jpg"
    }
}

Stage {
    title: "Image Load and Display"

    scene: Scene {
        width: 500
        height: 500
        content: [
            ImageView {
                 image: image
                 x: 10
                 y: 10
                 //Use fitWidth or fitHeight when scaling is required
                 //fitWidth: 480
                 // The following variables apply when scaling occurs
                 //preserveRatio: true
                 //smooth: true
            }
        ]
     }
 }
 

Tips

  • If you use a placeholder image, make sure that the file size is small so that it loads quickly.
  • If the image is large, set the backgroundLoading variable of the Image class to true.
  • For faster loading, size the image to the exact size needed for display, rather than using the fitWidth and fitHeight variables. Use the fitWidth and fitHeight variables for situations such as zooming in and out. In the latter case, size the original image to the largest size that the application requires, and reduce the size for zoom out.
  • If you use the fitWidth and fitHeight variables, set the preserveRatio variable to true if you want to preserve the height-to-width ratio of the graphic.
  • If the placeholder image is smaller than the main image and you use either the fitWidth or fitHeight variable to load the image, the placeholder will be resized to those dimensions also. For this reason, consider making the placeholder image the same size as the image if you plan to use the fitWidth or fitHeight variable.
  • If the image is scaled with the fitWidth or fitHeight variables, set the smooth variable to true to use a betterquality filtering algorithm, or to false to use a faster filtering algorithm. The default value is platform dependent.
  • PNG files that are saved from Adobe Fireworks preserve vector information, which might cause the loading of the graphic to fail when you run your JavaFX application. Ensure that you use the Export command in Fireworks to export to a completely rasterized PNG file.
  • If you are loading a series of images, you can use the following code.
    //Declare a sequence variable to hold the images
    var images:Image[]; 
    
    //Add file names to another sequence variable
    var files = [
            "image1.jpg", "image2.jpg", "image3.jpg",
        ];
    
    //Step through the file names and load the images
    for(one in files) {
        var image = Image{
            url: "resources/{one}"
        }
        insert image into images;
    }

API Documentation

How do I load and manipulate Production Suite graphics?


If you want to know more about Production Suite and the FXZ and FXD graphics file formats that it produces, see the About Production Suite section and the links to beginner topics at the bottom of this page.

If you have a JavaFX graphic (in FXZ format), you can choose from several different ways to load the graphic into your application. These alternatives break down into two main categories:

  • Loading the graphic synchronously, which means the application thread is stopped while the image loads
  • Loading the graphic asynchronously, which means the graphic loads in the background while the application thread continues

After the graphic is loaded, you can apply the same types of animations, effects, and event handlers to the graphic objects that you would apply to other nodes.

The following examples use a simple graphic that was developed in Inkscape and converted from SVG to JavaFX format. All of the code examples load the graphic and move the stars to new positions, as shown in the following figure.

Inkscape drawing and stars application

When the graphic is exported, an FXZ file is created, which contains an FXD content description. The FXD content description of this image is shown in the section About Production Suite.

Example Code 1: Synchronous Loading With the FXDNode Class

One way to load the image is to use FXDNode class, as shown in the following code. After the image is loaded, the node can be displayed in the scene in the normal fashion.

import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.fxd.FXDNode;

def URL = "{__DIR__}stars.fxz";
def fxdNode = FXDNode { url: URL};
def layer1 = fxdNode.getGroup("layer1");
def layer2 = fxdNode.getGroup("layer2");
layer1.translateX = 20;
layer1.translateY = 100;
layer2.translateX = 150;
layer2.translateY = 200;

Stage {
    title: "Production Suite graphic"
    width: 600
    height: 600
    scene: Scene {
        content: [
            fxdNode
        ]
     }
 }
 

Example Code 2: Synchronous Loading by Using LoadContent() and getRoot()

Another way to load and display the contents of a JavaFX graphic synchronously is to use the LoadContent() function of the FXDLoader class to load the file, then use the getRoot() function of the FXDContent class to obtain the topmost node of the loaded file. In the following code example, the stars.fxz file is loaded, variables are assigned to each layer, and the layers are repositioned.

import javafx.fxd.FXDLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;

def URL = "{__DIR__}stars.fxz";
def fxdContent = FXDLoader.loadContent(URL);
def layer1 = fxdContent.getGroup("layer1");
def layer2 = fxdContent.getGroup("layer2");
layer1.translateX = 20;
layer1.translateY = 100;
layer2.translateX = 150;
layer2.translateY = 200;
Stage {
    title: "Production Suite graphic"
    scene: Scene {
        width: 600
        height: 600
        content: [
            fxdContent.getRoot()
        ]
    }
}

Example Code 3: Synchronous Loading From a UI Stub

Another way to load the graphic is to use a shortcut available in the NetBeans IDE. You can generate a UI stub file, which contains a custom class that extends FXDNode. The custom class contains code that loads the graphic and generates a variable for each graphic object with an ID value.

You can then simply refer to the generated class, because it is loaded in the UI stub. The following code example calls the UI stub file, named starsUI.fx, and moves the layered objects to new positions.

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

def stars=starsUI{};
stars.layer1.translateX = 20;
stars.layer1.translateY = 100;
stars.layer2.translateX = 150;
stars.layer2.translateY = 200;
Stage {
    title: "Production Suite graphic"
    width: 600
    height: 600
    scene: Scene {
        content: [
            stars
        ]
     }
 }
 

Example Code 4: Asynchronous Loading

If the FXZ file is large, you can load it in the background by using the backgroundLoading variable of the FXDNode class. Here is one way to load the FXZ graphic asynchronously. With asynchronous loading, the layer positioning needs to be put into an onDone() function, because it has to run after the graphic is loaded.

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.fxd.FXDLoader;
import javafx.fxd.FXDNode;
import javafx.scene.text.Text;

var URL = "{__DIR__}stars.fxz";
var fxdNode: FXDNode=FXDNode {
    url: URL
    backgroundLoading: true
    placeholder: Text { x: 10 y: 10 content: "Loading graphics ..."}
    loader: FXDLoader {
        onDone: function() {
            var layer1 = fxdNode.getGroup("layer1");
            var layer2 = fxdNode.getGroup("layer2");
            layer1.translateX = 20;
            layer1.translateY = 100;
            layer2.translateX = 150;
            layer2.translateY = 200;
        }
    }
};

Stage {
    title: "Production Suite graphic"
    width: 600
    height: 600
    scene: Scene {
        content: [
            fxdNode
        ]
     }
 }
 

Example Code 5: Asynchronous Loading With a UI Stub File

The backgroundLoading variable of the FXDNode class can be applied to the UI stub file, because the UI stub custom class extends FXDNode.

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.fxd.FXDLoader;
import javafx.scene.text.Text;

var URL = "{__DIR__}stars.fxz";
var fxdNode: starsUI=starsUI {
    url: URL
    backgroundLoading: true
    placeholder: Text { x: 10 y: 10 content: "Loading graphics ..."}
    loader: FXDLoader {
        onDone: function() {
            var layer1 = fxdNode.getGroup("layer1");
            var layer2 = fxdNode.getGroup("layer2");
            layer1.translateX = 20;
            layer1.translateY = 100;
            layer2.translateX = 150;
            layer2.translateY = 200;
        }
    }
};

Stage {
    title: "Production Suite graphic"
    width: 600
    height: 600
    scene: Scene {
        content: [
            fxdNode
        ]
     }
 }
 

Developer Help for Production Suite

The following documents provide more information about how developers can work with graphic objects exported by using JavaFX Production Suite.

About Production Suite

Production Suite is a JavaFX application that converts Adobe Illustrator, Photoshop, and SVG graphics to JavaFX format. The advantage of using JavaFX graphics is that, for example, individual objects within the graphic can be programmatically moved and animated and have event handlers assigned to them. This means that designers can potentially create a single graphic for an entire application instead of delivering each object separately.

The exported FXZ file has an ID value assigned to Individual graphic objects, or an ID value assigned only to objects that are named with a jfx: prefix, if that option is selected. The ID value is the name that the designer assigned to that graphic object, which facilitates the workflow between designer and developer. For example, the following graphic was created in InkScape and exported to JavaFX graphics format (FXZ) using the SVG Converter in JavaFX Production Suite:

Inkscape SVG graphic

FXZ format is a compressed archive that contains an FXD file and supporting assets, such as PNG files or embedded fonts. The FXD file is a text description of the file that has many of the same elements as JavaFX Script code. The following examples shows a typical FXD description of the gray star layer:

Group {
content: [
Group {
id: "layer1"
transforms: [
Transform.translate(-99.42512, -120.33326)
]
content: [
SVGPath {
content: "M 188.57143,323.79075 L 109.73135,309.80522 L 53.514759,366.82317 
    L 42.452868,287.52003 L -29.146308,251.67439 L 42.857144,216.64789 
    L 54.823013,137.47612 L 110.38548,195.13169 L 189.37997,182.04648 
    L 151.71602,252.70608 L 188.57143,323.79075 z"
fill: Color.rgb(0x80, 0x80, 0x80, 1.0)
id: "path2385"
opacity: 1
strokeWidth: 2.0
transforms: [
Transform.translate(145.59746, -8.35889)
]
},
SVGPath {
content: "M 188.57143,323.79075 L 109.73135,309.80522 L 53.514759,366.82317 
    L 42.452868,287.52003 L -29.146308,251.67439 L 42.857144,216.64789 
    L 54.823013,137.47612 L 110.38548,195.13169 L 189.37997,182.04648 
    L 151.71602,252.70608 L 188.57143,323.79075 z"
fill: Color.rgb(0xb6, 0xb6, 0xdc, 1.0)
id: "path2383"
opacity: 1
strokeWidth: 2.0
transforms: [
Transform.translate(128.57143, -17.142859)
]
}
]
},
Group {
id: "layer2"
transforms: [
Transform.translate(-99.42512, -120.33326)
]
content: [
SVGPath {
content: "M 188.57143,323.79075 L 109.73135,309.80522 L 53.514759,366.82317 
    L 42.452868,287.52003 L -29.146308,251.67439 L 42.857144,216.64789 
    L 54.823013,137.47612 L 110.38548,195.13169 L 189.37997,182.04648 
    L 151.71602,252.70608 L 188.57143,323.79075 z"
fill: Color.rgb(0x80, 0x80, 0x80, 1.0)
id: "path3213"
opacity: 1
strokeWidth: 2.0
transforms: [
Transform.translate(319.82477, 33.17595)
]
},
SVGPath {
content: "M 188.57143,323.79075 L 109.73135,309.80522 L 53.514759,366.82317 
    L 42.452868,287.52003 L -29.146308,251.67439 L 42.857144,216.64789 
    L 54.823013,137.47612 L 110.38548,195.13169 L 189.37997,182.04648 
    L 151.71602,252.70608 L 188.57143,323.79075 z"
fill: Color.rgb(0xff, 0xff, 0x00, 1.0)
id: "path3215"
opacity: 1
strokeWidth: 2.0
transforms: [
Transform.translate(302.7987, 24.391989)
]
}
]
}
]
}

Note: Inkscape stores the values of custom layer names in a nonstandard inkscape:label attribute in the <g> element. The <g> element"s id attribute, which is the standard attribute for storing layer names, retains the default layer names, for example layer1 and layer2. For this reason, graphics converted from SVG files saved in Inkscape with the Production Suite SVG Converter lose the custom layer names and preserve the default layer names as ID values in the JavaFX content description. Saving the Inkscape file in plain SVG format does not help. It removes attributes in the inkscape: namespace, so the custom layer names stored in the inkspace:label attribute are removed. Creating SVG graphics with a tool such as Adobe Illustrator avoids this problem.

Beginner Help for JavaFX Production Suite

API Documentation

Last Updated: January 2010
[Return to How-To's Home]



Rate This Article
Leave a Comment or Suggest a Topic

Do you have comments about this article? We welcome your participation in our community. Please keep your comments civil and on point. You may optionally provide your email address to be notified of replies—your information is not used for any other purpose. By submitting a comment, you agree to these Terms of Use.

 

English
日本語
한국어
简体中文
русский
Português do Brasil