This discussion is archived
6 Replies Latest reply: Mar 15, 2013 6:57 PM by 866629 RSS

FXML + DisplayShelf Example

866629 Newbie
Currently Being Moderated
Hi There,

I'm playing around with the displayShelf sample that comes with Netbeans and I'm dabbling in FXML for the first time.
However, for the most part I'm coping with it, but one thing is pissing me off big time. No matter how hard I try
with using the example in conjunction with Scene Builder - FXML, for the life of me I cannot seem to get
setOnKeyPressed in this displayShelf example to work.

Basically I'm using the example as is, inside the controller class the only difference is that I do not use the init, or start
method from this displayShelf sample:

Shelf shelf = new Shelf(images);
displayShelf.getChildren().add(shelf);

whereby ...

@FXML
private HBox displayShelf;

This HBox is added to other layouts, hence the need to use it.

In FXML the displayShelf is a HBox, that has Focus Travsersable checked in Scene Builder. I even tried under the
Code Accordion tab in Scene Builder to assign a #handleKeyInput from my controller class. But even this has no
effect. Can anyone enlighten me on how to get this working?

Edited by: 863626 on 13/03/2013 16:19
  • 1. Re: FXML + DisplayShelf Example
    shakir.gusaroff Expert
    Currently Being Moderated
    This HBox is added to other layouts, hence the need to use it.
    The scenegraph only allows for nodes to be in one place at a time.
  • 2. Re: FXML + DisplayShelf Example
    866629 Newbie
    Currently Being Moderated
    Sorry your answer does not really assist me in solving my problem, because it does not guide me in how things should or can be done differently
    to get the event handler working.
  • 3. Re: FXML + DisplayShelf Example
    jsmith Guru
    Currently Being Moderated
    I looked at the DisplayShelf code, there is no Shelf class, it does not use a HBox and there is no Accordion in it.
    http://download.oracle.com/otndocs/products/javafx/2.2/samples/Ensemble/index.html#SAMPLES/Graphics/Display%20Shelf

    Your answer is likely unanswerable as it is.
    Post all of your source code and fxml files if you would like somebody to replicate your issue and help you solve it.

    The comment "This HBox is added to other layouts, hence the need to use it." is suspect because the Node documentation (http://docs.oracle.com/javafx/2/api/javafx/scene/Node.html) states:
    A node may occur at most once anywhere in the scene graph. Specifically, a node must appear no more than once in all of the following: as the root node of a Scene, the children ObservableList of a Parent, or as the clip of a Node.
    ...
    If a program adds a child node to a Parent (including Group, Region, etc) and that node is already a child of a different Parent or the root of a Scene, the node is automatically (and silently) removed from its former parent. If a program attempts to modify the scene graph in any other way that violates the above rules, an exception is thrown, the modification attempt is ignored and the scene graph is restored to its previous state.

    It is possible to rearrange the structure of the scene graph, for example, to move a subtree from one location in the scene graph to another. In order to do this, one would normally remove the subtree from its old location before inserting it at the new location. However, the subtree will be automatically removed as described above if the application doesn't explicitly remove it.
    From your comment, it would seem that you want to take this same HBox instance and place it in multiple layouts simultaneously, which is not possible. Perhaps that is not what you mean, but that seemed to be the intent of the statement to me.
  • 4. Re: FXML + DisplayShelf Example
    866629 Newbie
    Currently Being Moderated
    Hi J Smith,

    What I was trying to explain is that I'm using 90% of the code from the display shelf example 'as is' that comes in Netbeans.
    Including the portion of code in the Shelf class where it has setOnKeyPressed.

    The main difference is that I am not using the init and start methods of this example.

    I copied the remaining 90% of code into my controller class java file.

    Where the example has the following line:

    Shelf displayShelf = new Shelf(images);

    I'm instead trying to attach the region object that comes from the Shelf Class and adding it to an HBox layout that I have
    in the GUI I'm playing around with in the Scene Builder programme.

    Hence in the Controller file, I have:

    @FXML
    public void doSomething()
    {     //Loop thru first to obtain the image files

    Shelf s = new Shelf(images);
    displayShelf.getChildren().add(s);
    }

    @FXML private HBox displayShelf;

    Now the HBox I call displayShelf is added to another layout object (another HBox) as it only represents a portion of my overall
    GUI if you catch my drift. So what I was trying to say is that I add this node to other nodes in the scenegraph. I'm only using
    ONE scenegraph and the displayShelf HBox is only added to one parent object. I can see and manipulate the image carousel,
    however, the setOnKeyPressed never seems to catch key events, or respond to the left or right keyboard buttons.

    Edited by: 863626 on 13/03/2013 23:11
  • 5. Re: FXML + DisplayShelf Example
    jsmith Guru
    Currently Being Moderated
    the setOnKeyPressed never seems to catch key events, or respond to the left or right keyboard button
    Your Shelf region does not have input focus. You can request input focus using:
    displayShelf.requestFocus();
    To request focus when the mouse enters the displayShelf, you can use something like:
    displayShelf.setOnMouseEntered(new EventHandler<MouseEvent>() {
      @Override public void handle(MouseEvent t) {
          displayShelf.requestFocus();
      }
    });
    You could also trigger the focus request off of some other event if you wished, such as a mouse press, an app wide hot key or when some other control loses focus.

    Attached is a modified version of the DisplayShelf example. The modified version includes the code to focus the display shelf when the mouse enters it and remove focus from the display shelf when the mouse leaves it. When the shelf is focused it glows to provide a visual indication that it has focus. The modified version adds a TextField to the scene enclosing the shelf. This allows testing of the focus handling of the scene. Without the code which focuses the shelf on mouse enter, after you click on the TextField, it is difficult to get focus back to the DisplayShelf so that it will be able to process key events.

    As DisplayShelf is part of Ensemble and Ensemble is BSD licensed, I guess it's OK to post the modified version to the Oracle forums. The modifications are pretty minimal and all occur in the init method. I just include the whole thing here to make it easy to copy and paste in run (which I think is a useful thing in both questions and answers).
    /**
     * Copyright (c) 2008, 2012 Oracle and/or its affiliates.
     * All rights reserved. Use is subject to license terms.
     * 
     * Some modifications for mouse handling, styling and default icon usage made by John Smith in 2013.
     *   image license: linkware - backlink to http://www.fasticon.com
     */
    import javafx.application.Application;
    import javafx.stage.Stage;
    import javafx.animation.*;
    import javafx.beans.*;
    import javafx.beans.property.*;
    import javafx.beans.value.ChangeListener;
    import javafx.beans.value.ObservableValue;
    import javafx.collections.ObservableList;
    import javafx.event.EventHandler;
    import javafx.scene.*;
    import javafx.scene.control.*;
    import javafx.scene.effect.*;
    import javafx.scene.image.*;
    import javafx.scene.input.*;
    import javafx.scene.layout.*;
    import javafx.scene.shape.Rectangle;
    import javafx.util.Duration;
    
    public class DisplayShelfSample extends Application {
        private static final double WIDTH = 450, HEIGHT = 300;
    
        String[] imageLocs = {
          "http://icons.iconarchive.com/icons/fasticon/fish-toys/128/Blue-Fish-icon.png",
          "http://icons.iconarchive.com/icons/fasticon/fish-toys/128/Red-Fish-icon.png",
          "http://icons.iconarchive.com/icons/fasticon/fish-toys/128/Yellow-Fish-icon.png",
          "http://icons.iconarchive.com/icons/fasticon/fish-toys/128/Green-Fish-icon.png"
        };
        
        private void init(Stage stage) {
            VBox root = new VBox(10);
            root.setStyle("-fx-background-color: cadetblue;");
            stage.setScene(new Scene(root));
             // load images
            Image[] images = new Image[imageLocs.length + 4];
            for (int i = 0; i < imageLocs.length; i++) {
                images[i] = new Image(imageLocs);
    }
    // create display shelf
    final TextField fishCollectionName = new TextField("Mr Ray");
    final DisplayShelf displayShelf = new DisplayShelf(images);
    displayShelf.setPrefSize(WIDTH, HEIGHT);
    displayShelf.setOnMouseEntered(new EventHandler<MouseEvent>() {
    @Override public void handle(MouseEvent t) {
    displayShelf.requestFocus();
    }
    });
    displayShelf.setOnMouseExited(new EventHandler<MouseEvent>() {
    @Override public void handle(MouseEvent t) {
    fishCollectionName.requestFocus();
    fishCollectionName.deselect();
    }
    });
    final Glow glow = new Glow();
    displayShelf.focusedProperty().addListener(new ChangeListener<Boolean>() {
    @Override public void changed(ObservableValue<? extends Boolean> ov, Boolean wasFocused, Boolean focused) {
    if (focused) {
    displayShelf.setEffect(glow);
    } else {
    displayShelf.setEffect(null);
    }
    }
    });
    HBox.setHgrow(fishCollectionName, Priority.ALWAYS);
    root.getChildren().setAll(displayShelf,
    HBoxBuilder.create()
    .spacing(10)
    .style("-fx-padding: 10; -fx-background-color: cadetblue;")
    .children(
    new Label("Fish school name: "),
    fishCollectionName
    )
    .build()
    );
    }

    /**
    * A ui control which displays a browsable display shelf of images
    */
    public static class DisplayShelf extends Region {
    private static final Duration DURATION = Duration.millis(500);
    private static final Interpolator INTERPOLATOR = Interpolator.EASE_BOTH;
    private static final double SPACING = 50;
    private static final double LEFT_OFFSET = -110;
    private static final double RIGHT_OFFSET = 110;
    private static final double SCALE_SMALL = 0.7;
    private PerspectiveImage[] items;
    private Group centered = new Group();
    private Group left = new Group();
    private Group center = new Group();
    private Group right = new Group();
    private int centerIndex = 0;
    private Timeline timeline;
    private ScrollBar scrollBar = new ScrollBar();
    private boolean localChange = false;
    private Rectangle clip = new Rectangle();

    public DisplayShelf(Image[] images) {
    // set clip
    setClip(clip);
    // set background gradient using css
    setStyle("-fx-background-color: linear-gradient(to bottom," +
    " cadetblue 60, darkseagreen 60.1%, cadetblue 100%);");
    // style scroll bar color
    scrollBar.setStyle("-fx-base: cadetblue; -fx-background: cadetblue;");
    // create items
    items = new PerspectiveImage[images.length];
    for (int i=0; i<images.length; i++) {
    final PerspectiveImage item =
    items[i] = new PerspectiveImage(images[i]);
    final double index = i;
    item.setOnMouseClicked(new EventHandler<MouseEvent>() {
    public void handle(MouseEvent me) {
    localChange = true;
    scrollBar.setValue(index);
    localChange = false;
    shiftToCenter(item);
    }
    });
    }
    // setup scroll bar
    scrollBar.setMax(items.length-1);
    scrollBar.setVisibleAmount(1);
    scrollBar.setUnitIncrement(1);
    scrollBar.setBlockIncrement(1);
    scrollBar.valueProperty().addListener(new InvalidationListener() {
    public void invalidated(Observable ov) {
    if(!localChange)
    shiftToCenter(items[(int)scrollBar.getValue()]);
    }
    });
    // create content
    centered.getChildren().addAll(left, right, center);
    getChildren().addAll(centered,scrollBar);
    // listen for keyboard events
    setFocusTraversable(true);
    setOnKeyPressed(new EventHandler<KeyEvent>() {
    public void handle(KeyEvent ke) {
    if (ke.getCode() == KeyCode.LEFT) {
    shift(1);
    localChange = true;
    scrollBar.setValue(centerIndex);
    localChange = false;
    } else if (ke.getCode() == KeyCode.RIGHT) {
    shift(-1);
    localChange = true;
    scrollBar.setValue(centerIndex);
    localChange = false;
    }
    }
    });
    // update
    update();
    }

    @Override protected void layoutChildren() {
    // update clip to our size
    clip.setWidth(getWidth());
    clip.setHeight(getHeight());
    // keep centered centered
    centered.setLayoutY((getHeight() - PerspectiveImage.HEIGHT) / 2);
    centered.setLayoutX((getWidth() - PerspectiveImage.WIDTH) / 2);
    // position scroll bar at bottom
    scrollBar.setLayoutX(10);
    scrollBar.setLayoutY(getHeight()-25);
    scrollBar.resize(getWidth()-20,15);
    }

    private void update() {
    // move items to new homes in groups
    left.getChildren().clear();
    center.getChildren().clear();
    right.getChildren().clear();
    for (int i = 0; i < centerIndex; i++) {
    left.getChildren().add(items[i]);
    }
    center.getChildren().add(items[centerIndex]);
    for (int i = items.length - 1; i > centerIndex; i--) {
    right.getChildren().add(items[i]);
    }
    // stop old timeline if there is one running
    if (timeline!=null) timeline.stop();
    // create timeline to animate to new positions
    timeline = new Timeline();
    // add keyframes for left items
    final ObservableList<KeyFrame> keyFrames = timeline.getKeyFrames();
    for (int i = 0; i < left.getChildren().size(); i++) {
    final PerspectiveImage it = items[i];
    double newX = -left.getChildren().size() *
    SPACING + SPACING * i + LEFT_OFFSET;
    keyFrames.add(new KeyFrame(DURATION,
    new KeyValue(it.translateXProperty(), newX, INTERPOLATOR),
    new KeyValue(it.scaleXProperty(), SCALE_SMALL, INTERPOLATOR),
    new KeyValue(it.scaleYProperty(), SCALE_SMALL, INTERPOLATOR),
    new KeyValue(it.angle, 45.0, INTERPOLATOR)));
    }
    // add keyframe for center item
    final PerspectiveImage centerItem = items[centerIndex];
    keyFrames.add(new KeyFrame(DURATION,
    new KeyValue(centerItem.translateXProperty(), 0, INTERPOLATOR),
    new KeyValue(centerItem.scaleXProperty(), 1.0, INTERPOLATOR),
    new KeyValue(centerItem.scaleYProperty(), 1.0, INTERPOLATOR),
    new KeyValue(centerItem.angle, 90.0, INTERPOLATOR)));
    // add keyframes for right items
    for (int i = 0; i < right.getChildren().size(); i++) {
    final PerspectiveImage it = items[items.length - i - 1];
    final double newX = right.getChildren().size() *
    SPACING - SPACING * i + RIGHT_OFFSET;
    keyFrames.add(new KeyFrame(DURATION,
    new KeyValue(it.translateXProperty(), newX, INTERPOLATOR),
    new KeyValue(it.scaleXProperty(), SCALE_SMALL, INTERPOLATOR),
    new KeyValue(it.scaleYProperty(), SCALE_SMALL, INTERPOLATOR),
    new KeyValue(it.angle, 135.0, INTERPOLATOR)));
    }
    // play animation
    timeline.play();
    }

    private void shiftToCenter(PerspectiveImage item) {
    for (int i = 0; i < left.getChildren().size(); i++) {
    if (left.getChildren().get(i) == item) {
    int shiftAmount = left.getChildren().size() - i;
    shift(shiftAmount);
    return;
    }
    }
    if (center.getChildren().get(0) == item) {
    return;
    }
    for (int i = 0; i < right.getChildren().size(); i++) {
    if (right.getChildren().get(i) == item) {
    int shiftAmount = -(right.getChildren().size() - i);
    shift(shiftAmount);
    return;
    }
    }
    }

    public void shift(int shiftAmount) {
    if (centerIndex <= 0 && shiftAmount > 0) return;
    if (centerIndex >= items.length - 1 && shiftAmount < 0) return;
    centerIndex -= shiftAmount;
    update();
    }
    }

    /**
    * A Node that displays a image with some 2.5D perspective rotation around the Y axis.
    */
    public static class PerspectiveImage extends Parent {
    private static final double REFLECTION_SIZE = 0.25;
    private static final double WIDTH = 200;
    private static final double HEIGHT = WIDTH + (WIDTH*REFLECTION_SIZE);
    private static final double RADIUS_H = WIDTH / 2;
    private static final double BACK = WIDTH / 10;
    private PerspectiveTransform transform = new PerspectiveTransform();
    /** Angle Property */
    private final DoubleProperty angle = new SimpleDoubleProperty(45) {
    @Override protected void invalidated() {
    // when angle changes calculate new transform
    double lx = (RADIUS_H - Math.sin(Math.toRadians(angle.get())) * RADIUS_H - 1);
    double rx = (RADIUS_H + Math.sin(Math.toRadians(angle.get())) * RADIUS_H + 1);
    double uly = (-Math.cos(Math.toRadians(angle.get())) * BACK);
    double ury = -uly;
    transform.setUlx(lx);
    transform.setUly(uly);
    transform.setUrx(rx);
    transform.setUry(ury);
    transform.setLrx(rx);
    transform.setLry(HEIGHT + uly);
    transform.setLlx(lx);
    transform.setLly(HEIGHT + ury);
    }
    };
    public final double getAngle() { return angle.getValue(); }
    public final void setAngle(double value) { angle.setValue(value); }
    public final DoubleProperty angleModel() { return angle; }

    public PerspectiveImage(Image image) {
    ImageView imageView = new ImageView(image);
    imageView.setEffect(ReflectionBuilder.create().fraction(REFLECTION_SIZE).build());
    setEffect(transform);
    getChildren().addAll(imageView);
    }
    }

    public double getSampleWidth() { return 495; }

    public double getSampleHeight() { return 300; }

    @Override public void start(Stage primaryStage) throws Exception {
    init(primaryStage);
    primaryStage.show();
    }
    public static void main(String[] args) { launch(args); }
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
  • 6. Re: FXML + DisplayShelf Example
    866629 Newbie
    Currently Being Moderated
    Hi J Smith,

    You're a legend! Thank you for your suggestions, advice and perseverance...

    In my case the missing link for me was:

    To request focus when the mouse enters the displayShelf, you can use something like:
    displayShelf.setOnMouseEntered(new EventHandler<MouseEvent>() {
      @Override public void handle(MouseEvent t) {
          displayShelf.requestFocus();
      }
    });

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points