Skip to content

Instantly share code, notes, and snippets.

@jewelsea
Created December 12, 2012 10:33
Show Gist options
  • Save jewelsea/4266740 to your computer and use it in GitHub Desktop.
Save jewelsea/4266740 to your computer and use it in GitHub Desktop.
JRuby + JavaFX with FXML demonstration
This is a ruby version of: https://gist.github.com/3062859 "JavaFX fxml combo box selection demonstration app"
Build and execution instructions.
1. Clone https://github.com/nahi/jrubyfx
2. Build jrubyfx and make sure the default AnalogClock sample runs.
3. Place fruitcombo.css, fruitcombo.fxml and fruitcombo.rb in the jrubyfx samples directory.
4. Place FruitComboController.java in jrubyfx src directory under src/org/jewelsea/examples/jruby/fruit
5. Compile the java code using `ant jar`
6. Run the jruby sample using `ant run`
7. When prompted for the jrubyfx script, enter `samples/FruitCombo.rb`
8. JavaFX app will run.
9. App will display a UI where, upon choosing fruit from a combobox, an image of the selected fruit will be display.
Tested on Mac OSX 8 + JDK7u9
/** fruitcombo.css
place in same directory as fruitcombo.fxml */
.layout {
-fx-background-color: cornsilk;
}
#selected-fruit-frame {
-fx-border-color: burlywood;
-fx-border-width: 5;
-fx-background-color: white;
}
.bold-label {
-fx-font-weight: bold;
}
<?xml version="1.0" encoding="UTF-8"?>
<!-- fruitcombo.fxml -->
<?import java.lang.*?>
<?import java.net.*?>
<?import java.util.*?>
<?import javafx.collections.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<?scenebuilder-stylesheet fruitcombo.css?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="205.0" prefWidth="168.0" styleClass="layout" xmlns:fx="http://javafx.com/fxml">
<children>
<ComboBox fx:id="fruitCombo" layoutX="15.0" layoutY="33.0" prefWidth="90.0" promptText="choose">
<items>
<FXCollections fx:factory="observableArrayList">
<String fx:value="Apple" />
<String fx:value="Orange" />
<String fx:value="Pear" />
</FXCollections>
</items>
</ComboBox>
<Label id="fruitSelectorLabel" layoutX="15.0" layoutY="10.0" styleClass="bold-label" text="Fruit Selector" />
<VBox alignment="TOP_CENTER" layoutX="14.0" layoutY="62.0" prefHeight="134.0" prefWidth="140.0" spacing="8.0">
<children>
<StackPane id="selected-fruit-frame" minHeight="100.0" minWidth="118.0" prefHeight="108.0" prefWidth="140.0">
<children>
<ImageView fx:id="orangeImage" fitHeight="91.99999237060547" fitWidth="122.66666035739114" pickOnBounds="true" preserveRatio="true" visible="false">
<image>
<Image url="http://i.i.com.com/cnwk.1d/i/tim/2011/03/10/orange_iStock_000001331357X_540x405.jpg" preserveRatio="false" smooth="false" />
</image>
</ImageView>
<ImageView fx:id="pearImage" fitHeight="93.0" fitWidth="124.0" pickOnBounds="true" preserveRatio="true" visible="false">
<image>
<Image url="http://smoothiejuicerecipes.com/pear.jpg" preserveRatio="false" smooth="false" />
</image>
</ImageView>
<ImageView fx:id="appleImage" fitHeight="93.0" fitWidth="124.0" pickOnBounds="true" preserveRatio="true" visible="false">
<image>
<Image url="http://uhallnyu.files.wordpress.com/2011/11/green-apple.jpg" preserveRatio="false" smooth="false" />
</image>
</ImageView>
</children>
</StackPane>
<Label fx:id="selectedFruit" textAlignment="CENTER" />
</children>
</VBox>
</children>
<stylesheets>
<URL value="@fruitcombo.css" />
</stylesheets>
</AnchorPane>
require 'jrubyfx'
java_import 'java.net.URL'
java_import 'javafx.fxml.FXMLLoader'
java_import 'javafx.fxml.JavaFXBuilderFactory'
java_import 'org.jewelsea.examples.jruby.fruit.FruitComboController'
class FruitCombo
include JRubyFX
def start(stage)
# load your fxml file (adjust the path as necessary).
controller = FruitComboController.new
layout = fxml_load('file:/Users/lilyshard/dev/jrubyfx/samples/fruitcombo.fxml', controller)
# display the fxml generated layout on the stage.
with(stage,
title: "Choices",
scene: build(Scene,
layout)).show
end
def fxml_load(loc, controller)
# load the fxml into a javafx layout referenced via a Java controller.
url = URL.new(loc)
loader = FXMLLoader.new
loader.setBuilderFactory(JavaFXBuilderFactory.new)
loader.setLocation(url)
loader.setController(controller)
layout = loader.load(url.openStream)
# perform post javafx object injection scene initialization
fxml_init(controller)
return layout
end
# initialize with a controller which holds references to the fxml generated JavaFX objects
def fxml_init(c)
# bind the selected fruit label to the selected fruit in the combo box.
c.selected_fruit.text_property.bind c.fruit_combo.selection_model.selected_item_property
# listen for changes to the fruit combo box selection and update the displayed fruit image accordingly.
c.fruit_combo.selection_model.selected_item_property.add_listener SelectionChanger.new c
end
end
# respond to fruit selections by updating the visible images
class SelectionChanger
include Java::javafx.beans.value.ChangeListener
# initialize with a controller which holds references to the fxml generated JavaFX objects
def initialize(c)
@c = c
end
# implement the JavaFX ChangeListener interface
def changed(selected, oldFruit, newFruit)
unless oldFruit.nil?
case oldFruit
when "Apple"
@c.apple_image.visible = false
when "Orange"
@c.orange_image.visible = false
when "Pear"
@c.pear_image.visible = false
end
end
unless newFruit.nil?
case newFruit
when "Apple"
@c.apple_image.visible = true
when "Orange"
@c.orange_image.visible = true
when "Pear"
@c.pear_image.visible = true
end
end
end
end
FruitCombo.start
package org.jewelsea.examples.jruby.fruit;
import javafx.fxml.FXML;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.image.ImageView;
/** JavaFX fxml controller for fruit combo fxml demo application. */
public class FruitComboController {
@FXML
private ImageView appleImage; // Value injected by FXMLLoader
@FXML
private ComboBox<String> fruitCombo; // Value injected by FXMLLoader
@FXML
private ImageView orangeImage; // Value injected by FXMLLoader
@FXML
private ImageView pearImage; // Value injected by FXMLLoader
@FXML
private Label selectedFruit; // Value injected by FXMLLoader
public ImageView getAppleImage() {
return appleImage;
}
public void setAppleImage(ImageView appleImage) {
this.appleImage = appleImage;
}
public ComboBox<String> getFruitCombo() {
return fruitCombo;
}
public void setFruitCombo(ComboBox<String> fruitCombo) {
this.fruitCombo = fruitCombo;
}
public ImageView getOrangeImage() {
return orangeImage;
}
public void setOrangeImage(ImageView orangeImage) {
this.orangeImage = orangeImage;
}
public ImageView getPearImage() {
return pearImage;
}
public void setPearImage(ImageView pearImage) {
this.pearImage = pearImage;
}
public Label getSelectedFruit() {
return selectedFruit;
}
public void setSelectedFruit(Label selectedFruit) {
this.selectedFruit = selectedFruit;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment