4 Replies Latest reply: Nov 21, 2012 6:50 PM by 971987 RSS

    Hover never turns off

    971987
      Trying to create a new control and am working with the control/skin/behavior triumvirate. So far, I believe I understand how things are working, but I have one problem I can't decipher. Upon hover my control, I get the appropriate changes to color, but on mouse exit there's no reversion back to the non-hovered state, and nothing I do seems to make a difference. Here's the relevant portions of my code, stolen mostly from ChoiceBox and Button so far (as I'm working on a bit of a hybrid).
      public class DropDownButton extends ButtonBase {
      
        public DropDownButton () {
      
          super();
      
          setSkinClassName(DropDownButtonSkin.class.getName());
          setFocusTraversable(true);
        }
      
        public DropDownButton (String text) {
      
          super(text);
      
          setSkinClassName(DropDownButtonSkin.class.getName());
          setFocusTraversable(true);
        }
      
        public DropDownButton (String text, Node image) {
      
          super(text, image);
      
          setSkinClassName(DropDownButtonSkin.class.getName());
          setFocusTraversable(true);
        }
      
        @Override
        public void fire () {
      
        }
      }
      public class DropDownButtonSkin extends SkinBase<DropDownButton, ButtonBehavior<DropDownButton>> {
      
        private final StackPane openButton;
        private final Label label;
      
        public DropDownButtonSkin (DropDownButton dropDownButton) {
      
          super(dropDownButton, new ButtonBehavior<DropDownButton>(dropDownButton));
      
          getStylesheets().add(DropDownButton.class.getResource("DropDownButton.css").toExternalForm());
          getStyleClass().add("drop-down-box");
      
          label = new Label("Foo Bar");
          label.getStyleClass().add("label");
          label.setMnemonicParsing(false);
      
          openButton = new StackPane();
          openButton.getStyleClass().add("open-button");
      
          StackPane region = new StackPane();
          region.getStyleClass().add("arrow");
          openButton.getChildren().addAll(region);
      
          getChildren().setAll(label, openButton);
      
          requestLayout();
        }
      
        @Override
        protected void layoutChildren () {
      
          label.resizeRelocate(getInsets().getLeft(), getInsets().getTop(), label.prefWidth(-1), label.prefHeight(-1));
          openButton.resizeRelocate(getInsets().getLeft() + getWidth() - (openButton.prefWidth(-1) + getInsets().getRight()), getInsets().getTop() + ((getHeight() - openButton.prefHeight(-1)) / 2), openButton.prefWidth(-1), openButton.prefHeight(-1));
        }
      
        @Override
        protected double computeMinWidth (double height) {
      
          return computePrefWidth(height);
        }
      
        @Override
        protected double computeMinHeight (double width) {
      
          return computePrefHeight(width);
        }
      
        @Override
        protected double computePrefWidth (double height) {
      
          return getInsets().getLeft() + label.prefWidth(height) + openButton.prefWidth(-1) + getInsets().getRight();
        }
      
        @Override
        protected double computePrefHeight (double width) {
      
          return getInsets().getTop() + label.prefHeight(width) + getInsets().getBottom();
        }
      
        @Override
        protected double computeMaxWidth (double height) {
      
          return computePrefWidth(height);
        }
      
        @Override
        protected double computeMaxHeight (double width) {
      
          return computePrefHeight(width);
        }
      }
      .drop-down-box {
        -fx-skin: "org.smallmind.javafx.popup.DropDownButtonSkin";
        -fx-background-color: -fx-shadow-highlight-color, -fx-outer-border, -fx-inner-border, -fx-body-color;
        -fx-background-insets: 0 0 -1 0, 0, 1, 2;
        -fx-background-radius: 5, 5, 4, 3;
        -fx-padding: 0.0em 0.5em 0.0em 0.0em; /* 0 6 0 0 */
        -fx-alignment: CENTER;
        -fx-content-display: LEFT;
      }
      
      .drop-down-box:focused {
        -fx-color: -fx-focused-base;
        -fx-background-color: -fx-focus-color, -fx-outer-border, -fx-inner-border, -fx-body-color;
        -fx-background-insets: -1.4, 0, 1, 2;
        -fx-background-radius: 6.4, 5, 4, 3;
      }
      
      .drop-down-box:hover {
        -fx-color: -fx-hover-base;
      }
      
      .drop-down-box:armed {
        -fx-color: -fx-pressed-base;
      }
      
      .drop-down-box:showing {
        -fx-color: -fx-pressed-base;
      }
      
      .drop-down-box .label {
        -fx-padding: 0.166667em 0.333333em 0.25em 0.5em; /* 2 4 3 6 */
        -fx-text-fill: -fx-text-base-color;
      }
      
      .drop-down-box .open-button {
        -fx-background-color: null;
        -fx-padding: 0.083333em 0.0em 0.0em 0.666667em; /* 1 0 0 8 */
      }
      
      .drop-down-box .arrow {
        -fx-background-color: -fx-mark-highlight-color, -fx-mark-color;
        -fx-background-insets: 1 0 -1 0, 0;
        /* padding determines the size of the arrow;
      this should match the design size in the SVG */
        -fx-padding: 0.166667em 0.333333em 0.166667em 0.333333em; /* 2 3.5 2 3.5 */
        -fx-shape: "M 0 0 h 7 l -3.5 4 z";
      }
      
      .drop-down-box:disabled {
        -fx-opacity: -fx-disabled-opacity;
      }
      What is the mechanism which drives the return to a non-hovered state? What am I missing?

      Any help appreciated.
        • 1. Re: Hover never turns off
          David Grieve
          Maybe add -fx-color to the .drop-down-box rule?
          • 2. Re: Hover never turns off
            971987
            Good guess, but it has no effect, and the hover color stays even after mouse exit.

            Thanks for trying though...
            • 3. Re: Hover never turns off
              David Grieve
              I'm not sure what release or build you are using. All I can say is that it works on my machine. I'm running JavaFX 8.0 - something close to b66. I had to make a couple of tweaks. I moved
               
                  getStylesheets().add(DropDownButton.class.getResource("DropDownButton.css").toExternalForm());
                  getStyleClass().add("drop-down-box");
              to DropDownButton's ctors and I got rid of calls to some methods that didn't exist. My test program looks like this:
                  @Override
                  public void start(Stage stage) throws Exception {
                      
                      DropDownButton btn = new DropDownButton("Test");
                      btn.setSkin(new DropDownButtonSkin(btn));
                      
                      StackPane pane = new StackPane();
                      pane.setPrefSize(100, 100);
                      pane.getChildren().add(btn);
                      
                      Scene scene = new Scene(pane);
                      stage.setScene(scene);
                      stage.show();
                      
                  }
              I changed the hover color to red just to be certain the style was being applied.
              • 4. Re: Hover never turns off
                971987
                Give the man the gold star, you are correct.

                If I put the style sheet and add the style class in the constructor of the control, as opposed to the skin, then it works. Why this makes the difference, I don't know. If anyone does, feel free to explain. At least I'm unblocked and can continue to my next problem.

                Thank you