T. There is the with() function, which allows you to write code against a control as if you were right inside of its class.
with()function accepts the
rootas an argument. The following closure argument manipulates
rootdirectly by referring to it as
this, which is safely interpreted as a
Buttonwas added to the
VBoxby calling its
apply()accomplish a similar task. They safely interpret the type they are targeting and allow manipulations to be done to it. However,
apply()returns the item it was targeting. Therefore, if you call
Buttonto manipulate, say, its font color and action, it is helpful the
Buttonreturns itself so as to not break the declaration and assignment flow.
Buttonis added to its "parent", which is a
Node, these three steps are so common that TornadoFX streamlines them for you using strategically placed extension functions, such as
button()as shown below.
apply()function call? And why are we using a function called
button()instead of an actual
VBox(or any targetable component) has an extension function called
button(). It accepts a text argument and an optional closure targeting a
Buttonit will instantiate.
Buttonwith the specified text, apply the closure to it, add it to the
VBoxit was called on, and then return it.
View, but assign it a builder function and avoid needing any
HBoxinstances into a
VBox, and create UI code that is clearly structured (Figure 4.1).
Also note we will learn about TornadoFX's proprietary
Formlater, which will make simple input UI's like this even simpler to build.
singleAssign()delegates to ensure the properties are only assigned once.
useMaxWidthis an extended property for
Node, and it sets the
Nodeto occupy the maximum width allowed. We will see more of these helpful extensions throughout the next few chapters. We will also see each corresponding builder for each JavaFX control. With the concepts understood above, you can read about these next chapters start to finish or as a reference.
TextField. The next chapter will cover builders for data-driven controls like
Pane, you can call its
button()extension function to add a
Buttonto it. You can optionally pass a
textargument and a
Button.() -> Unitlambda to modify its properties.
Buttonwith red text and print "Button pressed!" every time it is clicked (Figure 4.2)
label()extension function to add a
Labelto a given
Pane. Optionally you can provide a text (of type
Property<String>), a graphic (of type
ObjectProperty<Node>) and a
Label.() -> Unitlambda to modify its properties (Figure 4.3).
TextFieldby calling its
textfield()extension function (Figure 4.4).
TextField. For example, we can add a listener to its
textProperty()and print its value every time it changes (Figure 4.5).
TextFieldto take sensitive information, you might want to consider a
PasswordFieldinstead. It will show anonymous characters to protect from prying eyes. You can also provide an initial password as an argument and a block to manipulate it (Figure 4.7).
CheckBoxto quickly create a true/false state control and optionally manipulate it with a block (Figure 4.8).
isSelectedproperty. If you do not need access to the properties of the
CheckBox, you can just express it like this.
Property<Boolean>that will bind to its selection state.
ComboBoxis a drop-down control that allows a fixed set of values to be selected from (Figure 4.10).
valuesas an argument.
Property<T>to be bound to the selected value.
ToggleButtonis a button that expresses a true/false state depending on its selection state (Figure 4.11).
StringBindingbound to the
togglebutton()function. This will ensure all
ToggleButtons in that
ToggleGroupcan only have one in a selected state at a time (Figure 4.12).
RadioButtonhas the same functionality as a
ToggleButtonbut with a different visual style. When it is selected, it "fills" in a circular control (Figure 4.13).
ToggleButton, you can set a
RadioButtonto be included in a
ToggleGroupso that only one item in that group can be selected at a time (Figure 4.14).
DatePickerallows you to choose a date from a popout calendar control. You can optionally provide a block to manipulate it (Figure 4.15).
Property<LocalDate>as an argument to bind to its value.
TextAreaallows you input multiline freeform text. You can optionally provide the initial text
valueas well as a block to manipulate it on declaration (Figure 4.16).
ProgressBarvisualizes progress towards completion of a process. You can optionally provide an initial
Doublevalue less than or equal to 1.0 indicating percentage of completion (Figure 4.17).
Property<Double>that will bind the
progressto its value as well as a block to manipulate the
ProgressIndicatoris functionally identical to a
ProgressBarbut uses a filling circle instead of a bar (Figure 4.18).
ProgressBaryou can provide a
Property<Double>and/or a block as optional arguments (Figure 4.19).
ScrollPaneto make it scrollable. When the available area becomes smaller than the control, scrollbars will appear to navigate the control's area.
TreeTableViewalready have scroll bars on them, so wrapping them in a
ScrollPaneis not necessary (Figure 4.22).
Hyperlinkcontrol to mimic the behavior of a typical hyperlink to a file, a website, or simply perform an action.
Textwith formatted properties. This control is simpler and rawer than a
Label, and paragraphs can be separated using characters (Figure 4.23).
TextFlowcontrol can be helpful (Figure 4.24).
textflow, including images, using the standard builder functions.
Nodeyou can specify a
tooltip()function (Figure 4.25).
shortcutfunction that does the same but is less verbose:
action, which can be configured on any
consumeparameter which by default is
false. Setting it to true will prevent event bubbling for the press event. The
longpressfunction additionally supports a
thresholdparameter which is used to determine when a
longpresshas occurred. It is
ImageView. In the coming chapters we will learn about builders for tables, layouts, menus, charts, and other controls. As you will see, combining all these builders together creates a powerful way to express complex UI's with very structured and minimal code.