6 Replies Latest reply: Mar 15, 2013 8:57 PM by 866629 RSS

    FXML + DisplayShelf Example

    866629
      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
          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
            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
              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
                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
                  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
                    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();
                      }
                    });