title: JavaFX ChoiceBox ContextMenu Position
body: <p>I am new to stackoverflow and also to Java programming, though I do have some small programming background.</p>
  
  <p>I am building a little program using JavaFX 8.0.0-b132 and JavaSE 8...</p>
  
  <p>The program has a GUI and this GUI has a ChoiceBox. The architecture for the layout is:
  AnchorPane - VBox - TitledPane - GridPane - HBox - ChoiceBox</p>
  
  <p>I have modified the ChoiceBox extensively using CSS.</p>
  
  <p>Everything is working as it should except for one problem:</p>
  
  <p>When I start the program and open the ChoiceBox (per mouse click or with show()) for the first time, it will display it's ContextMenu at the bottom edge as it should; however, when I close and open it again (with mouse or programmatically) it will display the ContextMenu on top of the ChoiceBox open-button (wrong y position), such that the bottom of the currently selected cell coincides with the bottom of the open-button (meaning it will change position after I select another cell and open it again).</p>
  
  <p>How do I prevent this and make the ContextMenu appear always at the bottom as it does at first?
  Here is a snippet of the GUI part of the program with the affected control:</p>
  
  <p>EDIT: problem solved: apparently this behavior is the intended ChoiceBox behavior; I posted in the JavaFX forums that it would be better to make the popup behave like that from the start i.e. the first time it is opened so as not to seem buggy.</p>
  
  <pre><code>import javafx.application.Application;
  import javafx.event.ActionEvent;
  import javafx.scene.input.MouseEvent;
  import javafx.event.EventHandler;
  import javafx.scene.Scene;
  import javafx.scene.control.*;
  import javafx.scene.layout.HBox;
  import javafx.scene.layout.VBox;
  import javafx.scene.text.*;
  import javafx.scene.layout.GridPane;
  import javafx.scene.layout.AnchorPane;
  import javafx.stage.Stage;
  import javafx.geometry.Insets;
  import javafx.collections.*;
  import javafx.beans.value.ChangeListener;
  import javafx.beans.value.ObservableValue;
  import javafx.geometry.Side;
  
  public class bugdemo extends Application {
  
      // Elements needed in both threads
  
      RadioButton radioBoxersOne = new RadioButton("One");
      RadioButton radioBoxersTwo = new RadioButton("Two");
  
      TextField warmupText = new TextField("skip warm up");
      TextField noCyclesText = new TextField("3");
      TextField cycleTimeText = new TextField("45");
      TextField restingTimeText = new TextField("30");
  
      String[] warmupTFtext = {"skip warm up", "\u00FCberspringen"};
  
      public static void main(String... args) {
          launch(args);
      }
  
      @Override
      public void start(Stage primaryStage) {
  
          // root container
          AnchorPane anchor = new AnchorPane();
  
          // Options TitledPane
          GridPane trainingOptions = new GridPane();
          ToggleGroup toggleGroup = new ToggleGroup();
          radioBoxersOne.setToggleGroup(toggleGroup);
          radioBoxersTwo.setToggleGroup(toggleGroup);
          radioBoxersOne.setSelected(true);
          HBox hbToggle = new HBox(15, radioBoxersOne, radioBoxersTwo);
          hbToggle.setPadding(new Insets(5,0,0,0));
  
          ObservableList&lt;String&gt; langList = FXCollections.observableArrayList("English", "Deutsch");
          ChoiceBox&lt;String&gt; langBox = new ChoiceBox&lt;String&gt;(langList);
          langBox.setValue("English");
          HBox hbLangBox = new HBox(0, langBox);
          hbLangBox.setPadding(new Insets(5,0,0,0));
  
          Label warmupOptionsLabel = new Label("Warm up time (min): ");
          Label noCyclesOptionsLabel = new Label("Number of cycles: ");
          Label cycleOptionsLabel = new Label("Cycle time (sec): ");
          Label restingOptionsLabel = new Label("Resting time (sec): ");
          Label noBoxersOptionsLabel = new Label("Number of boxers: ");
          Label langOptionsLabel = new Label("Language: ");
  
          trainingOptions.add(warmupOptionsLabel, 0, 0);
          trainingOptions.add(noCyclesOptionsLabel, 0, 1);
          trainingOptions.add(cycleOptionsLabel, 0, 2);
          trainingOptions.add(restingOptionsLabel, 0, 3);
          trainingOptions.add(noBoxersOptionsLabel, 0, 4);
          trainingOptions.add(langOptionsLabel, 0, 5);
          trainingOptions.add(warmupText, 1, 0);
          trainingOptions.add(noCyclesText, 1, 1);
          trainingOptions.add(cycleTimeText, 1, 2);
          trainingOptions.add(restingTimeText, 1, 3);
          trainingOptions.add(hbToggle, 1, 4);
          trainingOptions.add(hbLangBox, 1, 5);
  
          TitledPane TPane_in = new TitledPane("Options", trainingOptions);
  
          // Options TPane and Buttons together as UI (input)
          VBox UI = new VBox(10, /* hbButtons ,*/ TPane_in);
          anchor.getChildren().add(UI);
          AnchorPane.setLeftAnchor(UI, 25.0);
          AnchorPane.setTopAnchor(UI, 100.0);
  
          // EventHandlers for the radio-buttons
          radioBoxersOne.setOnAction(new EventHandler&lt;ActionEvent&gt;() {
  
              @Override
              public void handle(ActionEvent e) {
  /*              if (!singleBoxer){
                      trainingProgress.getChildren().remove(boxerLabel);
                      trainingProgress.getChildren().remove(boxerText);
                  }
                  changeTextFlow();
                  singleBoxer = true; */
              }
          });
  
          radioBoxersTwo.setOnAction(new EventHandler&lt;ActionEvent&gt;() {
  
              @Override
              public void handle(ActionEvent e) {
  /*              singleBoxer = false;
                  trainingProgress.add(boxerLabel, 0, 3);
                  trainingProgress.add(boxerText, 1, 3);
                  changeTextFlow(); */
              }
          });
  
          // "EventHandler" for the language ChoiceBox
          langBox.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener&lt;Number&gt;() {
              public void changed(ObservableValue ov, Number value, Number new_value) {
  /*              language = (int)new_value;
                  changeLanguage(); */
              }
          });
  
          // initialize scene and show stage
          Scene scene = new Scene(anchor, 800, 650);
          primaryStage.setScene(scene);
          primaryStage.setResizable(false);       // resizeable on/off
          // import CSS file
          // scene.getStylesheets().add(Letsbox.class.getResource("Training.css").toExternalForm());
          primaryStage.show();
          langBox.show();
          langBox.hide();
          langBox.show();
      }
  }
  </code></pre>
  
  <p>In this example no CSS is used, but the problem persists...</p>
  
  <p>I tried to fix it with:</p>
  
  <pre><code>/*      langBox.setOnMousePressed(new EventHandler&lt;MouseEvent&gt;() {
  
              @Override
              public void handle(MouseEvent e) {
                  ContextMenu cm = langBox.getContextMenu();
                  cm.show(cm.getOwnerNode(), Side.BOTTOM, 0.0, 0.0);
              }
          });  */
  </code></pre>
  
  <p>but it throws a NullPointerException...</p>
  
  <p>Please tell me how I could fix this :)</p>