Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8096941

[MAC] ComboBox unexpected behaviour in emedded mode

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Incomplete
    • Icon: P4 P4
    • None
    • 8u45
    • javafx
    • OS X 10.10.3
      Firefox / Safari
      Java 8.45

      For a special feature request, i have to avoid to close the combobox by a mouse click on the butten. To solve this problem, i've overidden the hide function of the combobox. That worked very well in all situations, except in the embedded mode under os x.

      code:
      public class ExtendedComboBox<T> extends ComboBox<T> {

      private final BooleanProperty autoHideProperty = new SimpleBooleanProperty(true);
      private Robot mouseRobot = Application.GetApplication().createRobot();

      @Override
      protected Skin<?> createDefaultSkin() {
              Skin<?> s = new ComboBoxListViewSkin<T>(this){
      @Override
               protected boolean isHideOnClickEnabled() {
               return getIsHideOnClickEnabled();
               }

      @Override
      protected PopupControl getPopup() {
      PopupControl p = super.getPopup();
      p.autoHideProperty().bind(autoHideProperty);
      return p;
      }
              };
        
              return s;
          }

      public boolean getIsHideOnClickEnabled() {return autoHideProperty.getValue();}
      public void setIsHideOnClickEnabled(Boolean value) { autoHideProperty.set(value);}
      public final BooleanProperty autoHideProperty(){ return autoHideProperty; }

      public void initComboBoxSpecialBehavior(){

      setIsHideOnClickEnabled(false);

           showingProperty().addListener(new ChangeListener<Boolean>() {

      @Override
      public void changed(ObservableValue<? extends Boolean> observable,
      Boolean oldValue, Boolean newValue) {
      final String selectedStyle = "combo-box-showing";

      if (newValue) {
      if(!getStyleClass().contains(selectedStyle)) {
      getStyleClass().add(selectedStyle);
      }
      }else if(getStyleClass().contains(selectedStyle)){
      getStyleClass().remove(selectedStyle);
      }
      }
      });
          
           setOnMouseEntered(new EventHandler<MouseEvent>() {
           @Override
      public void handle(MouseEvent event) {
           if(!isShowing()){
           show();
           }
      }
      });
          
           setOnMouseExited( new EventHandler<MouseEvent>() {
           @Override
      public void handle(MouseEvent event) {
           hide();
      }
      });
          
           addEventFilter(MouseEvent.MOUSE_RELEASED, new EventHandler<MouseEvent>() {

      @Override
      public void handle(MouseEvent event) {
      event.consume();
      hide();
      }
      });
          }

        @Override
          public void hide(){
           if(!isShowing()) return;
           Point2D point = ExtendedComboBox.this.localToScreen(getLayoutBounds().getMinX(), getLayoutBounds().getMinY());
      if(point == null) {
      return;
      }
      Bounds buttonBound = new BoundingBox(point.getX(), point.getY(), getWidth(), getHeight()+5); //+2 height necessary for mac, depending on popup-positioning

      if (!buttonBound.contains(mouseRobot.getMouseX(), mouseRobot.getMouseY())) {
      System.out.println("hide"+buttonBound.toString()+" getMouseX:"+mouseRobot.getMouseX()+" getMouseY:"+mouseRobot.getMouseY());
      super.hide();
      }
          }
      }

      public class ComboBoxTest extends Application {

      private ExtendedComboBox<String> createComboBox(){

      ObservableList<String> options = FXCollections.observableArrayList(
      "Option 1",
      "Option 2",
      "Option 3"
      );

      ExtendedComboBox<String> cp = new ExtendedComboBox<String>();
      cp.setItems(options);
      cp.setIsHideOnClickEnabled(false);
      cp.initComboBoxSpecialBehavior();
      return cp;
      }

      @Override
      public void start(Stage primaryStage) {
      try {

      StackPane root = new StackPane();

      Scene scene = new Scene(root,400,400);
      scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
      primaryStage.setScene(scene);
      primaryStage.show();

      root.getChildren().add(createComboBox());

      } catch(Exception e) {
      e.printStackTrace();
      }
      }

      public static void main(String[] args) {
      launch(args);
      }
      }

            kcr Kevin Rushforth
            duke J. Duke
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported: