Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Additional description support for label/value #21

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 142 additions & 0 deletions formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/Field.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.Labeled;

import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -120,6 +123,20 @@ public abstract class Field<F extends Field> {
final ListProperty<String> errorMessages = new SimpleListProperty<>(FXCollections.observableArrayList());
final ListProperty<String> errorMessageKeys = new SimpleListProperty<>(FXCollections.observableArrayList());

/**
* Additional descriptions for the field's label and value are stored in these properties.
*
* These properties are translatable if a {@link TranslationService} is set on
* the containing form.
*/
private Node labelDescription;
private Node valueDescription;
private final StringProperty labelDescriptionKey = new SimpleStringProperty("");
private final StringProperty valueDescriptionKey = new SimpleStringProperty("");

private static final String LABEL_DESCRIPTION_STYLE_CLASS = "field-label-description";
private static final String VALUE_DESCRIPTION_STYLE_CLASS = "field-value-description";

/**
* The translation service is passed down from the containing section. It
* is used to translate all translatable values of the field.
Expand Down Expand Up @@ -160,6 +177,10 @@ public abstract class Field<F extends Field> {

placeholderKey.addListener((observable, oldValue, newValue) -> placeholder.setValue(translationService.translate(newValue)));

labelDescriptionKey.addListener((observable, oldValue, newValue) -> labelDescription = asLabel(translationService.translate(newValue), LABEL_DESCRIPTION_STYLE_CLASS));

valueDescriptionKey.addListener((observable, oldValue, newValue) -> valueDescription = asLabel(translationService.translate(newValue), VALUE_DESCRIPTION_STYLE_CLASS));

requiredErrorKey.addListener((observable, oldValue, newValue) -> validate());

// Whenever the errorMessageKeys change, update the displayed
Expand Down Expand Up @@ -451,6 +472,89 @@ public F label(String newValue) {
return (F) this;
}

/**
* Sets the label description property of the current field.
*
* @param newValue
* The new value for the label description property.
*
*
* @return Returns the current field to allow for chaining.
*/
public F labelDescription(Node newValue) {
labelDescription = newValue;
if (labelDescription != null) {
labelDescription.getStyleClass().add(LABEL_DESCRIPTION_STYLE_CLASS);
}

return (F) this;
}

/**
* Sets the label description property of the current field.
*
* @param newValue
* The new value for the label description property,
* wrapped with a {@code Text}.
*
*
* @return Returns the current field to allow for chaining.
*/
public F labelDescription(String newValue) {
if(isI18N()) {
labelDescriptionKey.set(newValue);
} else if (newValue != null) {
labelDescription = asLabel(newValue, LABEL_DESCRIPTION_STYLE_CLASS);
}

return (F) this;
}

/**
* Sets the value description property of the current field.
*
* @param newValue
* The new value for the field description property.
*
*
* @return Returns the current field to allow for chaining.
*/
public F valueDescription(Node newValue) {
valueDescription = newValue;
if (valueDescription != null) {
valueDescription.getStyleClass().add(VALUE_DESCRIPTION_STYLE_CLASS);
}

return (F) this;
}

/**
* Sets the value description property of the current field.
*
* @param newValue
* The new value for the field description property,
* wrapped with a {@code Text}.
*
*
* @return Returns the current field to allow for chaining.
*/
public F valueDescription(String newValue) {
if(isI18N()) {
valueDescriptionKey.set(newValue);
} else if (newValue != null) {
valueDescription = asLabel(newValue, VALUE_DESCRIPTION_STYLE_CLASS);
}

return (F) this;
}

private Label asLabel(String text, String styleClass) {
Label label = new Label(text);
label.setWrapText(true);
label.getStyleClass().add(styleClass);
return label;
}

/**
* Sets the tooltip property of the current field.
*
Expand Down Expand Up @@ -589,6 +693,8 @@ public void translate(TranslationService newValue) {
updateElement(tooltip, tooltipKey);
updateElement(placeholder, placeholderKey);
updateElement(requiredError, requiredErrorKey);
updateElement(labelDescription, labelDescriptionKey);
updateElement(valueDescription, valueDescriptionKey);

// Validation results are handled separately as they use a somewhat
// more complex structure.
Expand Down Expand Up @@ -618,6 +724,35 @@ void updateElement(StringProperty displayProperty, StringProperty keyProperty) {
}
}

/**
* Updates a displayable field property to include translated text.
*
* @param node
* The property that is displayed to the user.
* @param keyProperty
* The internal property that holds the translation key.
*/
void updateElement(Node node, StringProperty keyProperty) {

// If the key has not yet been set that means that the translation
// service was added for the first time. We can simply set the key
// to the value stored in the display property, the listener will
// then take care of the translation.

if (!(node instanceof Labeled)) {
// no automatic update
return;
}

Labeled labeled = (Labeled) node;

if ((keyProperty.get() == null || keyProperty.get().isEmpty()) && !labeled.getText().isEmpty()) {
keyProperty.setValue(labeled.getText());
} else if (!keyProperty.get().isEmpty()) {
labeled.setText(translationService.translate(keyProperty.get()));
}
}

/**
* Validates a user input based on the field's value transformer and its
* validation rules. Also considers the {@code required} flag. This method
Expand Down Expand Up @@ -723,4 +858,11 @@ public ListProperty<String> errorMessagesProperty() {
return errorMessages;
}

public Node getLabelDescription() {
return labelDescription;
}

public Node getValueDescription() {
return valueDescription;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@
*/

import com.dlsc.formsfx.model.structure.BooleanField;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;

/**
Expand Down Expand Up @@ -66,10 +69,22 @@ public void initializeParts() {
public void layoutParts() {
super.layoutParts();

int columns = field.getSpan();
container.getChildren().add(checkBox);

add(fieldLabel, 0,0,2,1);
add(container, 2, 0, field.getSpan() - 2,1);
Node labelDescription = field.getLabelDescription();
Node valueDescription = field.getValueDescription();

add(fieldLabel, 0, 0, 2, 1);
if (labelDescription != null) {
GridPane.setValignment(labelDescription, VPos.TOP);
add(labelDescription, 0, 1, 2, 1);
}
add(container, 2, 0, columns - 2, 1);
if (valueDescription != null) {
GridPane.setValignment(valueDescription, VPos.TOP);
add(valueDescription, 2, 1, columns - 2, 1);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@
*/

import com.dlsc.formsfx.model.structure.MultiSelectionField;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;

import java.util.ArrayList;
Expand Down Expand Up @@ -73,8 +76,19 @@ public void layoutParts() {

box.setSpacing(5);

add(fieldLabel, 0,0,2,1);
add(box, 2, 0, columns - 2,1);
Node labelDescription = field.getLabelDescription();
Node valueDescription = field.getValueDescription();

add(fieldLabel, 0, 0, 2, 1);
if (labelDescription != null) {
GridPane.setValignment(labelDescription, VPos.TOP);
add(labelDescription, 0, 1, 2, 1);
}
add(box, 2, 0, columns - 2, 1);
if (valueDescription != null) {
GridPane.setValignment(valueDescription, VPos.TOP);
add(valueDescription, 2, 1, columns - 2, 1);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,11 @@

import com.dlsc.formsfx.model.structure.SingleSelectionField;
import javafx.geometry.Pos;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;

/**
Expand Down Expand Up @@ -82,8 +85,19 @@ public void layoutParts() {
stack.setAlignment(Pos.CENTER_LEFT);
stack.getChildren().addAll(comboBox, readOnlyLabel);

add(fieldLabel, 0,0,2,1);
Node labelDescription = field.getLabelDescription();
Node valueDescription = field.getValueDescription();

add(fieldLabel, 0, 0, 2, 1);
if (labelDescription != null) {
GridPane.setValignment(labelDescription, VPos.TOP);
add(labelDescription, 0, 1, 2, 1);
}
add(stack, 2, 0, columns - 2, 1);
if (valueDescription != null) {
GridPane.setValignment(valueDescription, VPos.TOP);
add(valueDescription, 2, 1, columns - 2, 1);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@

import com.dlsc.formsfx.model.structure.MultiSelectionField;
import javafx.collections.ListChangeListener;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.SelectionMode;
import javafx.scene.layout.GridPane;

/**
* This class provides the base implementation for a simple control to edit
Expand Down Expand Up @@ -82,8 +85,19 @@ public void layoutParts() {

listView.setPrefHeight(200);

add(fieldLabel, 0,0,2,1);
Node labelDescription = field.getLabelDescription();
Node valueDescription = field.getValueDescription();

add(fieldLabel, 0, 0, 2, 1);
if (labelDescription != null) {
GridPane.setValignment(labelDescription, VPos.TOP);
add(labelDescription, 0, 1, 2, 1);
}
add(listView, 2, 0, columns - 2, 1);
if (valueDescription != null) {
GridPane.setValignment(valueDescription, VPos.TOP);
add(valueDescription, 2, 1, columns - 2, 1);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,11 @@

import com.dlsc.formsfx.model.structure.DataField;
import javafx.geometry.Pos;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.Spinner;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;

/**
Expand Down Expand Up @@ -80,14 +83,34 @@ public void layoutParts() {

editableSpinner.setMaxWidth(Double.MAX_VALUE);

Node labelDescription = field.getLabelDescription();
Node valueDescription = field.getValueDescription();

int columns = field.getSpan();

if (columns < 3) {
add(fieldLabel, 0, 0, columns, 0);
add(stack, 0, 1, columns, 1);
int rowIndex = 0;
add(fieldLabel, 0, rowIndex++, columns, 1);
if (labelDescription != null) {
GridPane.setValignment(labelDescription, VPos.TOP);
add(labelDescription, 0, rowIndex++, columns, 1);
}
add(stack, 0, rowIndex++, columns, 1);
if (valueDescription != null) {
GridPane.setValignment(valueDescription, VPos.TOP);
add(valueDescription, 0, rowIndex, columns, 1);
}
} else {
add(fieldLabel, 0, 0, 2, 1);
if (labelDescription != null) {
GridPane.setValignment(labelDescription, VPos.TOP);
add(labelDescription, 0, 1, 2, 1);
}
add(stack, 2, 0, columns - 2, 1);
if (valueDescription != null) {
GridPane.setValignment(valueDescription, VPos.TOP);
add(valueDescription, 2, 1, columns - 2, 1);
}
}
}

Expand Down
Loading