I have a TableView
and a Hbox
below the table, in the hBox there are threeLabel
s one contains a text, and two contains the sum of two columns in the table. I want to set a spacing somehow dynamic for the HBox to align the two labels exactly below the two columns in the table to which they belong. Is there any possibility to bind the HBox
's spacing to the columns position.
I also accept any other solution that fixes the labels exactly below the respective columns.
Here is an image that shows what I want:
Asked
Active
Viewed 1,211 times
0

Sunflame
- 2,993
- 4
- 24
- 48
-
Is [this answer](https://stackoverflow.com/a/30509195/7214815) related to your problem? – Dmytro Maslenko Jul 28 '17 at 17:28
1 Answers
2
Bind each label's minWidth
and prefWidth
properties to the corresponding column's width
property:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class TableWithLabelsBelowColumns extends Application {
@Override
public void start(Stage primaryStage) {
TableView<Void> table = new TableView<>();
table.getItems().add(null);
TableColumn<Void, Void> firstNameColumn = new TableColumn<>("First Name");
TableColumn<Void, Void> lastNameColumn = new TableColumn<>("Last Name");
TableColumn<Void, Void> emailColumn = new TableColumn<>("Email");
table.getColumns().add(firstNameColumn);
table.getColumns().add(lastNameColumn);
table.getColumns().add(emailColumn);
Label fnLabel = new Label("FN");
Label lnLabel = new Label("LN");
Label emailLabel = new Label("E");
fnLabel.prefWidthProperty().bind(firstNameColumn.widthProperty());
fnLabel.minWidthProperty().bind(firstNameColumn.widthProperty());
lnLabel.prefWidthProperty().bind(lastNameColumn.widthProperty());
lnLabel.minWidthProperty().bind(lastNameColumn.widthProperty());
emailLabel.prefWidthProperty().bind(emailColumn.widthProperty());
emailLabel.minWidthProperty().bind(emailColumn.widthProperty());
HBox labels = new HBox(fnLabel, lnLabel, emailLabel);
BorderPane root = new BorderPane(table);
root.setBottom(labels);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
An alternative approach is to subclass Pane
and override the layoutChildren()
method to position the labels according to the widths of the columns. Register a listener to request layout on the pane with each column's width:
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
public class TableWithLabelsBelowColumns extends Application {
@Override
public void start(Stage primaryStage) {
TableView<Void> table = new TableView<>();
table.getItems().add(null);
TableColumn<Void, Void> firstNameColumn = new TableColumn<>("First Name");
TableColumn<Void, Void> lastNameColumn = new TableColumn<>("Last Name");
TableColumn<Void, Void> emailColumn = new TableColumn<>("Email");
table.getColumns().add(firstNameColumn);
table.getColumns().add(lastNameColumn);
table.getColumns().add(emailColumn);
Label fnLabel = new Label("FN");
Label lnLabel = new Label("LN");
Label emailLabel = new Label("E");
Pane labelPane = new Pane(fnLabel, lnLabel, emailLabel) {
@Override
protected void layoutChildren() {
double fnWidth = firstNameColumn.getWidth();
double fnHeight = fnLabel.prefHeight(fnWidth);
fnLabel.resizeRelocate(0, 0, fnWidth, fnHeight);
double lnWidth = lastNameColumn.getWidth();
double lnHeight = lnLabel.prefHeight(lnWidth);
lnLabel.resizeRelocate(fnWidth, 0, lnWidth, lnHeight);
double emailWidth = emailColumn.getWidth();
double emailHeight = emailLabel.prefHeight(emailWidth);
emailLabel.resizeRelocate(fnWidth+lnWidth, 0, emailWidth, emailHeight);
}
};
ChangeListener<? super Number> listener = (obs, oldValue, newValue) -> labelPane.requestLayout();
firstNameColumn.widthProperty().addListener(listener);
lastNameColumn.widthProperty().addListener(listener);
emailColumn.widthProperty().addListener(listener);
BorderPane root = new BorderPane(table);
root.setBottom(labelPane);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

James_D
- 201,275
- 16
- 291
- 322
-
I have just tried it, but it is not working when I try to use for 3rd and 4th column, especially the first solution. The second may work, I have to play a little bit with the numbers `fnLabel.resizeRelocate(here, and her, fnWidth, fnHeight);` – Sunflame Jul 31 '17 at 07:12
-
At first was trying to use this solution :https://stackoverflow.com/questions/30506075/javafx-how-to-make-a-line-of-summationtotal-row-in-the-bottom-of-the-table/30509195#30509195, but the problem is that line is an Item of the table, so when I sort, filter, and so on it gets sorted, filtered. – Sunflame Jul 31 '17 at 07:20
-
Finally I solved it using your second suggestion, I have also added at first `.resizeRelocate()` the width of the previous colums so it is working fine now. Thanks. – Sunflame Jul 31 '17 at 15:18