Как добавить границу в панель javafx?

Я разрабатываю приложение, в котором мне нужны некоторые виджеты для обертывания внутри панели. И я хочу разместить вокруг него границу. Я программист swt, где в составе я могу передать swt.border, чтобы установить границу. Но как это сделать в JavaFX. Любая помощь по этому поводу приветствуется.

CODE:

Label Center=new Label();
Center.setText("Center Frequency");

GridPane.setConstraints(Center, 0, 0);
tb1[i].getChildren().add(Center);
TextField text=new TextField();
GridPane.setConstraints(text, 1, 0);
tb1[i].getChildren().add(text);

Label chiprate=new Label();
chiprate.setText("Chiprate");

GridPane.setConstraints(chiprate, 0, 1);
tb1[i].getChildren().add(chiprate);
TextField chip=new TextField();
GridPane.setConstraints(chip, 1, 1);
tb1[i].getChildren().add(chip);

Label frequency=new Label();
frequency.setText("Frequency deviation");

GridPane.setConstraints(frequency, 0, 2);
tb1[i].getChildren().add(frequency);
TextField frequencydeviation=new TextField();
GridPane.setConstraints(frequencydeviation, 1, 2);
tb1[i].getChildren().add(frequencydeviation);

Label outputLabel=new Label();
outputLabel.setText("Output Power");

GridPane.setConstraints(outputLabel, 0, 3);
tb1[i].getChildren().add(outputLabel);
TextField output=new TextField();
GridPane.setConstraints(output, 1, 3);
tb1[i].getChildren().add(output);

Ответ 1

Я создаю класс BorderedTitledPane, который помещает обозначенную рамку вокруг содержимого.

Если вам не нужно, чтобы заголовок, помещающий границу вокруг вещей, еще проще - просто установите параметры границы css в регионе (например, -fx-border-color: black;).

Вот полный исполняемый образец.

borderedtitledpane

import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;

/** Places content in a bordered pane with a title. */
public class BorderedTitledPane extends StackPane {
  private StringProperty title = new SimpleStringProperty();
  private ObjectProperty<Node> graphic = new SimpleObjectProperty<>();
  private ObjectProperty<Node> content = new SimpleObjectProperty<>();
  private ObjectProperty<Pos>  titleAlignment = new SimpleObjectProperty<>();
  // todo other than TOP_LEFT other alignments aren't really supported correctly, due to translation fudge for indentation of the title label in css => best to implement layoutChildren and handle layout there.
  // todo work out how to make content the default node for fxml so you don't need to write a <content></content> tag.

  public BorderedTitledPane() {
    this("", null);
  }

  public BorderedTitledPane(String titleString, Node contentNode) {
    final Label titleLabel = new Label();
    titleLabel.textProperty().bind(Bindings.concat(title, " "));
    titleLabel.getStyleClass().add("bordered-titled-title");
    titleLabel.graphicProperty().bind(graphic);

    titleAlignment.addListener(new InvalidationListener() {
      @Override
      public void invalidated(Observable observable) {
        StackPane.setAlignment(titleLabel, titleAlignment.get());
      }
    });

    final StackPane contentPane = new StackPane();

    getStyleClass().add("bordered-titled-border");
    getChildren().addAll(titleLabel, contentPane);

    content.addListener(new InvalidationListener() {
      @Override
      public void invalidated(Observable observable) {
        if (content.get() == null) {
          contentPane.getChildren().clear();
        } else {
          if (!content.get().getStyleClass().contains("bordered-titled-content")) {
            content.get().getStyleClass().add("bordered-titled-content");  // todo would be nice to remove this style class when it is no longer required.
          }
          contentPane.getChildren().setAll(content.get());
        }
      }
    });

    titleAlignment.set(Pos.TOP_LEFT);
    this.title.set(titleString);
    this.content.set(contentNode);
  }

  public String getTitle() {
    return title.get();
  }

  public StringProperty getTitleStringProperty() {
    return title;
  }

  public void setTitle(String title) {
    this.title.set(title);
  }

  public Pos getTitleAlignment() {
    return titleAlignment.get();
  }

  public ObjectProperty<Pos> titleAlignmentProperty() {
    return titleAlignment;
  }

  public void setTitleAlignment(Pos titleAlignment) {
    this.titleAlignment.set(titleAlignment);
  }

  public Node getContent() {
    return content.get();
  }

  public ObjectProperty<Node> contentProperty() {
    return content;
  }

  public void setContent(Node content) {
    this.content.set(content);
  }

  public Node getGraphic() {
    return graphic.get();
  }

  public ObjectProperty<Node> graphicProperty() {
    return graphic;
  }

  public void setGraphic(Node graphic) {
    this.graphic.set(graphic);
  }
}

Связанный CSS.

.bordered-titled-title {
  -fx-translate-x:  8;
  -fx-translate-y: -10;
  -fx-padding: 0 0 0 4;
  -fx-background-color: -fx-background;
}

.bordered-titled-border {
  -fx-content-display: top;
  -fx-border-insets: 2 0 0 0;
  -fx-border-color: -fx-text-box-border;
  -fx-border-width: 2;
}

.bordered-titled-content {
  -fx-padding: 18 5 5 5;
}