|
|
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
The refactoring of Swing JPad is well underway, with basic features such as the content pane, menu system, and event handling successfully migrated to JavaFX 2. Now find out how more advanced features such as dialogs and drag-and-drop support map from Swing to JavaFX. Part 3 concludes with Jeff's response to the question of whether JavaFX 2 is production ready, and an opportunity to share your own perspective.
The second part of this article focused on the essential features of a notepad application converted from Swing to JavaFX 2. You've seen how Swing JPad's content pane, menu system, and event handling architecture map to JPadFX. Now, we'll conclude with a look at some of the more advanced features of a notepad application: dialog boxes, a clipboard, and drag-and-drop manipulation.
Like the original Swing notepad application, JPadFX presents dialog boxes for selecting a file from the filesystem, showing
About information, displaying error messages, and prompting the user for yes/no responses. In Listing 1, JPadFX's start() method instantiates javafx.stage.FileChooser to handle the file-selection task.
fc = new FileChooser();
fc.setInitialDirectory(new File("."));
FileChooser.ExtensionFilter ef1;
ef1 = new FileChooser.ExtensionFilter("TXT documents (*.txt)", "*.txt");
FileChooser.ExtensionFilter ef2;
ef2 = new FileChooser.ExtensionFilter("All Files", "*.*");
fc.getExtensionFilters().addAll(ef1, ef2);
After instantiating FileChooser, start() sets its initial directory to the current one. Because FileChooser offers only a no-argument constructor, the start() method uses fc.setInitialDirectory(new File(".")); instead of a constructor to set the directory.
Continuing, start() creates a pair of extension-based file filters by instantiating FileChooser's nested ExtensionFilter class. It registers them with the file chooser by returning an observable list of extension filters and adding the pair of
filters to this list.
JPadFX will use the file chooser to display an Open or Save dialog box by calling FileChooser's void showOpenDialog(Window ownerWindow) or void showSaveDialog(Window ownerWindow) method. Listing 2 demonstrates the former method in the context of JPadFX's doOpenFile(file) method.
if (file == null)
file = fc.showOpenDialog(stage);
if (file == null)
return;
fc.setInitialDirectory(file.getParentFile());
The fc.setInitialDirectory(file.getParentFile()); method ensures that the next file-chooser activation sets the initial directory to the current one.
Unlike JPad, which relies on Swing's JOptionPane class for its About, Alert, and AreYouSure dialog boxes, JPadFX has no JOptionPane equivalent, because JavaFX has yet to provide one. So we'll manually create the About, Alert, and AreYouSure dialog boxes
for JPadFX. As you will discover, each dialog box class extends JavaFX's Stage class, which means that a dialog box is nothing more than a secondary stage (as opposed to the primary stage that is passed
to the application's start() method).
JPad's About dialog box, which provides information about JPadFX in image and text form, is implemented by the About class. About's source code is shown in Listing 3.
public class About extends Stage
{
public About(Stage owner)
{
initOwner(owner);
initStyle(StageStyle.UNDECORATED);
initModality(Modality.APPLICATION_MODAL);
Group root = new Group();
Image img = new Image(getClass().getResourceAsStream("icon.png"));
ImageView iv = new ImageView(img);
double width = iv.layoutBoundsProperty().getValue().getWidth();
double height = iv.layoutBoundsProperty().getValue().getHeight();
iv.setX(10.0);
iv.setY((180.0-height)/2.0);
root.getChildren().add(iv);
Text msg1 = new Text("JPadFX 1.0");
msg1.setFill(Color.WHITE);
msg1.setFont(new Font("Arial", 20.0));
msg1.setX(iv.getX()+width);
msg1.setY(iv.getY()+height/2.0);
root.getChildren().add(msg1);
Text msg2 = new Text("by Jeff Friesen");
msg2.setFill(Color.WHITE);
msg2.setFont(new Font("Arial", 12.0));
msg2.setX(msg1.getX());
msg2.setY(msg1.getY()+20.0);
root.getChildren().add(msg2);
Reflection r = new Reflection();
r.setFraction(1.0);
root.setEffect(r);
Scene scene = new Scene(root, 200.0, 180.0, Color.BLACK);
EventHandler<MouseEvent> ehme;
ehme = new EventHandler<MouseEvent>()
{
@Override
public void handle(MouseEvent me)
{
close();
}
};
scene.setOnMousePressed(ehme);
setScene(scene);
setX(owner.getX()+Math.abs(owner.getWidth()-scene.getWidth())/2.0);
setY(owner.getY()+Math.abs(owner.getHeight()-scene.getHeight())/2.0);
}
}
In Listing 3, About's constructor takes a Stage argument, which identifies the stage that owns the About dialog box. The About dialog box is owned by the primary stage,
so JPadFX passes the primary stage instance to About's constructor via the expression newAbout(stage).show();.
Before the About box is displayed (by calling Stage's void show() method), JavaFX must be informed of this stage's owner. We do this by invoking Stage's void initOwner(Window owner) method with the argument passed to About's constructor.
Next we declare the stage's style and modality. First, we use a void initStyle(StageStyle style) method to inform JavaFX of the desired style for the stage. Calling this method with the javafx.stage.StageStyle enum's UNDECORATED constant tells JavaFX that the stage must not have a border or other decorations.
Next, Stage declares a void initModality(Modality modality) method, which informs JavaFX of the desired modality for the stage. This method is called with the javafx.stage.Modality enum's APPLICATION_MODAL constant, telling JavaFX not to deliver events to any other application window. Both the void initStyle(StageStyle style) and void initModality(Modality modality) methods must be called before the stage is displayed.
The constructor next instantiates the javafx.scene.Group class, which is a container node for subsequently created nodes. The first of these nodes is a javafx.scene.image.ImageView instance, which manages a javafx.scene.image.Image instance that describes an image.
More from JavaWorld