JavaFX Password Field

September 12th, 2009 by Martin Leave a reply »

As I mentioned in My First Experience with JavaFX blog, there is no password field in JavaFX, so I had to google for some workarounds. Although I found a few, none of them worked flawlessly, so last night I decided to spend some time trying to come up with a password field that would really work as expected. And, I think I managed to come up with an elegant and simple solution. No hacking in form of covering the text area with additional components or adding effects that blur the text box (including the caret and component borders). It looks and behaves exactly as you would expect of a password field. Click on the following picture to try it out:

Or click the following button for standalone mode:

And here is how it is implemented:

import javafx.scene.control.TextBox;
import javafx.util.Math;

/** * @author Martin Matula */
public class PasswordBox extends TextBox {
    public-read var password = "";

    override function replaceSelection(arg) {
        var pos1 = Math.min(dot, mark);
        var pos2 = Math.max(dot, mark);
        password = "{password.substring(0, pos1)}{arg}{password.substring(pos2)}";
        super.replaceSelection(getStars(arg.length()));
    }

    override function deleteNextChar() {
        if ((mark == dot) and (dot < password.length())) {
            password = "{password.substring(0, dot)}{password.substring(dot + 1)}";
        }
        super.deleteNextChar();
    }

    override function deletePreviousChar() {
        if ((mark == dot) and (dot > 0)) {
            password = "{password.substring(0, dot - 1)}{password.substring(dot)}";
        }
        super.deletePreviousChar();
    }

    function getStars(len: Integer): String {
        var result: String = "";
        for (i in [1..len]) {
            result = "{result}*";
        }
        result;
    }
}

Quite simple, isn’t it? Here is how it is used in the Main class:

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.text.Text;

var password: PasswordBox;

var stage: Stage = Stage {
    title: "PasswordBox Demo"
    width: 200
    height: 100
    scene: Scene {
        content: [
            password = PasswordBox {
                translateX: 10
                translateY: 10
                columns: 20
            },
            Text {
                x: 10
                y: 50
                content: bind password.password
            }
        ]
    }
}

I guess there is still a room for improving the API – the real password is stored in the password property, while the text property became useless and should never be set by a client. If you want to populate the field with a remembered password, you need to do it by calling replaceSelection("password") on the password field after it’s initialization (rather than setting the text or the password properties). Anyway, I wanted to keep the code simple so that you can easily see the basic idea behind it.

12 comments

  1. PhiLho says:

    Aah, a nice, simple implementation, with a smart usage of function overriding. Well done!
    Note, I have an alternative implementation of getStars, using the fact that a sequence of strings in an interpolated variable is made of concatenation of the strings.
    super.replaceSelection(“{for (i in [ 1 .. arg.length() ]) ‘*’}”);

  2. Richard Bair says:

    Hey Martin, very cool. Only thing I’d do differently is to have PasswordBox extend TextInputControl and use a TextBox in it’s skin implementation (delegation vs inheritance). One reason is that TextBox gains the ability to be multiline in the next realease which would be odd for a password box I guess.

    One other thing, does this implementation work with promptText?

  3. Tbee says:

    I also believe that it should be possible to preset a password textfield with a value (“remember password”)

  4. António Oliveira says:

    Thank for share the code.

  5. Deepak says:

    Thanks a lot for the code. Awesome implementation. Really useful

  6. rodrigo salado anaya says:

    perfecto… muy bueno y bonito , me gusto mucho :) gracias… yo are el mio basándome en el tuyo gracias…

  7. Pilla Gurumurty Patrudu says:

    Thank you – It was very useful.

Leave a Reply to Richard Bair