dlsc-software-consulting-gmbh / FormsFX

A framework for easily creating forms for a JavaFX UI.
Apache License 2.0
643 stars 94 forks source link

Setting width of Labels #52

Open pauliamgiant opened 4 years ago

pauliamgiant commented 4 years ago

Hi there,

Having difficulty setting the width of the Labels.. would be good to have room for a little more text. Have been able to adjust the individual widths of the label and the control with CSS but this is creating an overlap as shown in image below. Any help would be much appreciated!

Many thanks

.changeLabel .label {

-fx-font-family: "DS-Digital Bold";
-fx-font-size: 130%;
-fx-min-width:150px;

}

.changeLabel .combo-box-base{ -fx-max-width:150px; }

image
sunsteam commented 4 years ago

same question , I can't find width relative api, how to set adaptable width and height, like match_parent or wrap_content in Android ?


@Override
    public void start(Stage primaryStage) throws Exception {
        //Pane root = FXMLLoader.load(getClass().getResource("/layout/launcher.fxml"));
        Pane root = new Pane();
        primaryStage.setTitle("Demo");

        List<String> strings = Arrays.asList("Africa", "Asia", "Shanghai", "中国", "美国");

        Form form = Form.of(
                Group.of(
                        Field.ofMultiSelectionType(strings, Collections.singletonList(1))
                                .label("Continent")
                                .render(new SimpleCheckBoxControl<>())
                )
        );

        FormRenderer formRenderer = new FormRenderer(form);
        formRenderer.setFillWidth(true);
        root.getChildren().add(formRenderer);

        Scene scene = new Scene(root, 800, 600);
        primaryStage.setScene(scene);
        primaryStage.show();

    }

image

I write a simple demo look like above. then manually set width

Form form = Form.of(
                Group.of(
                        Field.ofMultiSelectionType(strings, Collections.singletonList(1))
                                .label("Continent")
                                .render(new SimpleCheckBoxControl<>() {
                                    @Override
                                    protected void setWidth(double value) {
                                        super.setWidth(400);
                                    }
                                })
                )
        );

image

but not smart and accurate enough.

Please Help.

sreese4u commented 3 years ago

Is this project dead? I started using this library and after 5 minutes I hit this issue. No response since few months now.

tanqidong1992 commented 3 years ago

You just need to set the width of the FormRenderer;

    val model=PermissionModel();
    val loginForm: Form = Form.of(
                Group.of(
                        Field.ofStringType(model.userName)
                                .label("Username")
                                .span(12)
                ),
                Group.of(
                        Field.ofStringType(model.password)
                                .label("Password")
                                .span(12)
                                .required("This field can’t be empty")
                )
        ).title("Login")
    val root = Pane()
    var fr=FormRenderer(loginForm);
    fr.prefWidth=600.0;
    root.children.add(fr);
    val stage=Stage();
    stage.scene= Scene(root);
    stage.title="add"
    stage.centerOnScreen();
    stage.show();

see com.dlsc.formsfx.view.controls.SimpleTextControl#layoutParts

/**
     * {@inheritDoc}
     */
    @Override
    public void layoutParts() {
        super.layoutParts();

        readOnlyLabel.getStyleClass().add("read-only-label");

        readOnlyLabel.setPrefHeight(26);

        editableArea.getStyleClass().add("simple-textarea");
        editableArea.setPrefRowCount(5);
        editableArea.setPrefHeight(80);
        editableArea.setWrapText(true);

        if (field.isMultiline()) {
            stack.setPrefHeight(80);
            readOnlyLabel.setPrefHeight(80);
        }

        stack.getChildren().addAll(editableField, editableArea, readOnlyLabel);

        stack.setAlignment(Pos.CENTER_LEFT);

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

        int columns = field.getSpan();

        if (columns < 3) {
            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);
            }
        }
    }

@sreese4u

Dimitry82 commented 3 years ago

q I have a similar question. How to increase the number of labels letters shown by sacrificing the width of the text field? In my case, a maximum of 7 letters are shown.

thamidu commented 2 years ago

I just did a few hours of digging and found out that they use gridpanes for the layout. So basically they make 12 cols which have 100/12 % width of full width. For the label, they assigned 2 columns with cols span which means the label area is only having 16.67 % of the whole width which isn't enough. So I implemented a workaround that and I post it here. Hope it helps for ya all.

/**
 * Set label width by percentage
 * @param pane probably the FormRenderer
 * @param labelSize label size by percentage. For ex. if the label needs half the space of width use 50
 */
private void searchAndSetControlsLabelWidth(Pane pane, double labelSize) {
    if(pane instanceof GridPane){
        if(pane.getStyleClass().stream().anyMatch(s -> s.contains("simple-"))){
            GridPane gp = (GridPane) pane;
            if (gp.getColumnConstraints().size() == 12) {
                double rest = 100 - labelSize;
                for (int i = 0; i < gp.getColumnConstraints().size(); i++) {
                    if (i < 3) {
                        gp.getColumnConstraints().get(i).setPercentWidth(labelSize / 2);
                    }
                    else {
                        gp.getColumnConstraints().get(i).setPercentWidth(rest/10);
                    }
                }
            }
        }
    }

    for (Node child : pane.getChildren()) {
        if (child instanceof Pane) {
            searchAndSetControlsLabelWidth((Pane) child, labelSize);
        }
    }
}

FormRenderer renderer = new FormRenderer(form);
searchAndSetControlsLabelWidth(renderer, 40);
deamn commented 2 years ago

A correction would be hopeful...

m0squito commented 2 years ago

Here is a small improvement to @thamidu's solution - it accounts for sections in the forms:

protected void searchAndSetControlsLabelWidth(Pane pane, double labelSize) {
  if (pane instanceof GridPane) {
      if (pane.getStyleClass().stream().anyMatch(s -> s.contains("simple-"))) {
          GridPane gp = (GridPane) pane;
          if (gp.getColumnConstraints().size() == 12) {
              double rest = 100 - labelSize;
              for (int i = 0; i < gp.getColumnConstraints().size(); i++) {
                  if (i < 3) {
                      gp.getColumnConstraints().get(i).setPercentWidth(labelSize / 2);
                  } else {
                      gp.getColumnConstraints().get(i).setPercentWidth(rest / 10);
                  }
              }
          }
      }
  }

  for (Node child : pane.getChildren()) {
      if (child instanceof Pane cpane) {
          searchAndSetControlsLabelWidth(cpane, labelSize);
      }

      else if (child instanceof TitledPane tpane) {
          if (tpane.getContent() instanceof Pane cpane) {
              searchAndSetControlsLabelWidth(cpane, labelSize);
          }
      }
  }
}