Module MaterialFX

Class MFXTextField

All Implemented Interfaces:
MFXMenuControl, Validated, Styleable, EventTarget, Skinnable
Direct Known Subclasses:
MFXComboBox, MFXDatePicker, MFXPasswordField

public class MFXTextField extends TextField implements Validated, MFXMenuControl
A modern text field restyled to follow material design principles and with many new features.

Unlike Swing and JavaFX (which copied Swing duh), I followed Google's Material Design guidelines. They do not have anything like a Label but only TextFields. After all, a TextField has all the features a Label has and even more.

MFXTextField allows you to make it behave like a Label by setting the TextInputControl.editableProperty() and the selectableProperty() to false.

Allows you to specify up to two icons (leading and trailing) and the gap between them and the text.

Unlike JavaFX's TextField, it also allows to easily change the text color (even with CSS).

But... the most important and requested feature is the floating text. You can decide between four modes: DISABLED (no floating text), INLINE (the floating text is inside the field), BORDER (the floating text is placed on the field's border, and ABOVE (the floating text is outside the field, above it).

You can also specify the distance between the text and the floating text (for INLINE and ABOVE modes). In ABOVE and BORDER modes you can control the floating text distance from the origin by modifying the left padding in CSS or by modifying the borderGapProperty().

MFXTextField now also introduces a new PseudoClass, ":floating" that activates when the floating text node is floating.

As with the previous MFXTextField it's also possible to specify the maximum number of characters for the text.

Some little side notes on the floating text:

Please note that because of the extra node to show the floating text, MFXTextField now takes more space. There are several things you can do to make it more compact:

1) You can lower the floatingTextGapProperty() (for INLINE and ABOVE mode)

2) You can lower the padding (set in CSS) but I would not recommend it to be honest, a little bit of padding makes the control more appealing

3) You can switch mode. The DISABLED mode requires the least space of course. The BORDER mode requires some more space, the ABOVE mode is visually equal to the DISABLED state but keep in mind that the floating text is still there, above the field, and the INLINE mode is the one that requires the most space.

The layout strategy now should be super solid and efficient, making possible to switch float modes even at runtime.

Note 1: in case of BORDER mode to make it really work as intended a condition must be met. The background colors of the text field, the floating text and the parent container of the field must be the same. You see, on the material.io website you can see the floating text cut the field's borders but that's not what it is happening. If you look more carefully the demo background is white, and the field's background as well. The floating text just sits on top of the field's border and has the same background color, creating that 'cut' effect.

Note 2: since JavaFX devs are shitheads making everything private/readonly/final, the only way to make the caret position and the selection consistent is to delegate related methods to the BoundTextField instance. This means that most if not all methods related to the caret and the selection WON'T work, instead you should use the methods that start with "delegate", e.g. delegateCaretPositionProperty(), delegateSelectionProperty(), etc...

Also note that the same applies to the focus property, delegateFocusedProperty().

Some methods that do not start with "delegate" may work as they've been overridden to be delegates, e.g. positionCaret(int), selectRange(int, int), etc...

If that's not the case then maybe I missed something so please report it back and I'll see if it's fixable.

Considering that the other option would have been re-implementing a TextField completely from scratch (really hard task) this is the best option as of now. Even just a custom skin would not work (yep I tried) since black magic is involved in the default one, better not mess with that or something will break for sure, yay for spaghetti coding JavaFX devs :D

Note 3: Since MFXTextFields (and all subclasses) are basically a wrapper for a TextField, and considered how focus works for them. To make focus behavior consistent in CSS, MFXTextField introduces a new PseudoClass "focus-within" which will be activated every time the inner TextField is focused and deactivated when it loses focus