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

xProperty does not bind in custom PasswordField

XMLWordPrintable

    • x86
    • windows_8

      FULL PRODUCT VERSION :
      java version "1.8.0_45"
      Java(TM) SE Runtime Environment (build 1.8.0_45-b15)
      Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Windows 8

      A DESCRIPTION OF THE PROBLEM :
      I extended the PasswordField control to create a control that is able to toggle the bullets inside the PasswordField on and off. Since the TextField itself is a parent-node I added an Image-object to the PasswordField and tried to bind it to the right inner side of the PasswordField.

      REGRESSION. Last worked in version 7u75

      ADDITIONAL REGRESSION INFORMATION:
      java version "1.7.0_75"
      Java(TM) SE Runtime Environment (build 1.7.0_75-b13)
      Java HotSpot(TM) 64-Bit Server VM (build 24.75-b04, mixed mode)

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. create a new PasswordField-component by extending the PasswordField-class.
      2. Add an ImageView-component as child to the PasswordField inside the constructor.
      3. bind the xProperty of the ImageView-object to the widthProperty minus the width of the ImageView itself.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The ImageView should be seen on the right inner side of the PasswordField.
      ACTUAL -
      The ImageView is set fixed in the center of the PasswordField-component.

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      no errors

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      public class TextPasswordFieldSkin extends com.sun.javafx.scene.control.skin.TextFieldSkin {

          public static final char BULLET = '\u2022';
          private TextPasswordField textPasswordField;

          public TextPasswordFieldSkin(TextPasswordField passwordField) {
              super(passwordField, new PasswordFieldBehavior(passwordField));
              this.textPasswordField = passwordField;
          }

          public void updateField() {
              super.getSkinnable().textProperty().setValue(super.getSkinnable().getText());
          }

          @Override
          protected String maskText(String txt) {
              TextField textField = getSkinnable();

              if (textPasswordField != null && textPasswordField.getActivatedValue()) {
                  int n = textField.getLength();
                  StringBuilder passwordBuilder = new StringBuilder(n);
                  for (int i = 0; i < n; i++) {
                      passwordBuilder.append(BULLET);
                  }
                  return passwordBuilder.toString();
              } else {
                  return textField.getText();
              }
          }
      }


      public class TextPasswordField extends PasswordField {

          private TextPasswordFieldSkin skin = new TextPasswordFieldSkin(this);
          private ImageView bulletEyeView;
          private Image bulletEye;

          private String activatedImage = "de/fiverx/testviews/images/eye-symbol-small-pressed.png";
          private String activatedHoveredImage = "de/fiverx/testviews/images/eye-symbol-small-pressed-hovered.png";
          private String deactivatedHoveredImage = "de/fiverx/testviews/images/eye-symbol-small-hover.png";
          private String deactivatedImage = "de/fiverx/testviews/images/eye-symbol-small.png";

          private SimpleBooleanProperty activatedValue = new SimpleBooleanProperty(true);

          public TextPasswordField() {
              super.setSkin(skin);
              bulletEye = new Image(getClass().getResourceAsStream("/" + activatedImage));
              bulletEyeView = new ImageView(bulletEye);
              this.getChildren().add(bulletEyeView);
              bulletEyeView.xProperty().bind(this.widthProperty().subtract(bulletEye.getWidth())); // the evil line that is not working in Java 8 but in Java 7

              bulletEyeView.setPickOnBounds(true);
              bulletEyeView.fitHeightProperty().bind(this.heightProperty());
              bulletEyeView.hoverProperty().addListener(new ChangeListener<Boolean>() {
                  public void changed(ObservableValue<? extends Boolean> observableValue, Boolean aBoolean, Boolean t1) {
                      if (t1) {
                          if (activatedValue.get()) {
                              bulletEyeView.styleProperty().setValue("-fx-image: url(\"" + activatedHoveredImage + "\");");
                          } else {
                              bulletEyeView.styleProperty().setValue("-fx-image: url(\"" + deactivatedHoveredImage + "\");");
                          }
                      } else {
                          if (activatedValue.get()) {
                              bulletEyeView.styleProperty().setValue("-fx-image: url(\"" + activatedImage + "\");");
                          } else {
                              bulletEyeView.styleProperty().setValue("-fx-image: url(\"" + deactivatedImage + "\");");
                          }
                      }
                  }
              });
              bulletEyeView.pressedProperty().addListener(new ChangeListener<Boolean>() {
                  private int counter = 2;
                  public void changed(ObservableValue<? extends Boolean> observableValue, Boolean aBoolean, Boolean t1) {
                      if (counter % 2 == 0) {
                          if (t1 && counter == 0) {
                              activatedValue.set(true);
                              if (bulletEyeView.hoverProperty().get()) {
                                  bulletEyeView.styleProperty().setValue(
                                          "-fx-image: url(\"" + activatedHoveredImage + "\");");
                              } else {
                                  bulletEyeView.styleProperty().setValue("-fx-image: url(\"" + activatedImage + "\");");
                              }
                          } else if (t1 && counter == 2) {
                              activatedValue.set(false);
                              if (bulletEyeView.hoverProperty().get()) {
                                  bulletEyeView.styleProperty().setValue("-fx-image: url(\"" + deactivatedHoveredImage + "\");");
                              } else {
                                  bulletEyeView.styleProperty().setValue("-fx-image: url(\"" + deactivatedImage + "\");");
                              }
                          }
                      }
                      counter++;
                      if (counter > 3) counter = 0;
                  }
              });
              activatedValue.addListener(new ChangeListener<Boolean>() {
                  public void changed(ObservableValue<? extends Boolean> observableValue, Boolean aBoolean, Boolean t1) {
                      skin.updateField();
                  }
              });
          }
      ...
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      no direct workarounds found...

            aghaisas Ajit Ghaisas
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved: