Javafx 如何设置一个TableColumn以与TableView一起增长?
我有一个Javafx 如何设置一个TableColumn以与TableView一起增长?,javafx,Javafx,我有一个TableView,它会随着窗口大小的调整而适当地收缩/增长 但是,我希望其中一列也能自动增长。类似于HGrow属性在其他节点上的工作方式 TableColumn似乎没有任何类型的HGrow或类似属性来告诉该列使用所有可用空间 我确实尝试将PrefWidth属性设置为Double.MAX\u值,但导致列无限扩展 我的目标是让TableView适合窗口,如果调整窗口大小,而不是展开最后一个伪列(实际上根本不是列),它将展开首选列 这是我的MCVE: import javafx.applic
TableView
,它会随着窗口大小的调整而适当地收缩/增长
但是,我希望其中一列也能自动增长。类似于HGrow
属性在其他节点上的工作方式
TableColumn
似乎没有任何类型的HGrow
或类似属性来告诉该列使用所有可用空间
我确实尝试将PrefWidth
属性设置为Double.MAX\u值
,但导致列无限扩展
我的目标是让TableView
适合窗口,如果调整窗口大小,而不是展开最后一个伪列(实际上根本不是列),它将展开首选列
这是我的MCVE:
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TableColumnGrow extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
// Simple Interface
VBox root = new VBox(10);
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(10));
TableView<Person> tableView = new TableView<>();
TableColumn<Person, String> colFirstName = new TableColumn<>("First Name");
TableColumn<Person, String> colLastName = new TableColumn<>("Last Name");
colFirstName.setCellValueFactory(tf -> tf.getValue().firstNameProperty());
colLastName.setCellValueFactory(tf -> tf.getValue().lastNameProperty());
tableView.getColumns().addAll(colFirstName, colLastName);
tableView.getItems().addAll(
new Person("Martin", "Brody"),
new Person("Matt", "Hooper"),
new Person("Sam", "Quint")
);
root.getChildren().add(tableView);
// Show the stage
primaryStage.setScene(new Scene(root));
primaryStage.setTitle("TableColumnGrow Sample");
primaryStage.show();
}
}
class Person {
private final StringProperty firstName = new SimpleStringProperty();
private final StringProperty lastName = new SimpleStringProperty();
public Person(String firstName, String lastName) {
this.firstName.set(firstName);
this.lastName.set(lastName);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String firstName) {
this.firstName.set(firstName);
}
public StringProperty firstNameProperty() {
return firstName;
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String lastName) {
this.lastName.set(lastName);
}
public StringProperty lastNameProperty() {
return lastName;
}
}
导入javafx.application.application;
导入javafx.beans.property.SimpleStringProperty;
导入javafx.beans.property.StringProperty;
导入javafx.geometry.Insets;
导入javafx.geometry.Pos;
导入javafx.scene.scene;
导入javafx.scene.control.TableColumn;
导入javafx.scene.control.TableView;
导入javafx.scene.layout.VBox;
导入javafx.stage.stage;
公共类TableColumnGrow扩展了应用程序{
公共静态void main(字符串[]args){
发射(args);
}
@凌驾
公共无效开始(阶段primaryStage){
//简单接口
VBox根=新的VBox(10);
根部设置对齐(位置中心);
根。设置填充(新插图(10));
TableView TableView=新建TableView();
TableColumn colFirstName=新的TableColumn(“名字”);
TableColumn colLastName=新的TableColumn(“姓氏”);
colFirstName.setCellValueFactory(tf->tf.getValue().firstNameProperty());
colLastName.setCellValueFactory(tf->tf.getValue().lastNameProperty());
tableView.getColumns().addAll(colFirstName、colLastName);
tableView.getItems().addAll(
新人(“马丁”、“布罗迪”),
新人(“马特”、“胡珀”),
新人(“Sam”、“Quint”)
);
root.getChildren().add(tableView);
//上台
primaryStage.setScene(新场景(根));
primaryStage.setTitle(“TableColumnGrow样本”);
primaryStage.show();
}
}
班主任{
private final StringProperty firstName=新SimpleStringProperty();
private final StringProperty lastName=新的SimpleStringProperty();
公众人物(字符串名、字符串名){
this.firstName.set(firstName);
this.lastName.set(lastName);
}
公共字符串getFirstName(){
返回firstName.get();
}
public void setFirstName(字符串firstName){
this.firstName.set(firstName);
}
public StringProperty firstNameProperty(){
返回名字;
}
公共字符串getLastName(){
返回lastName.get();
}
public void setLastName(字符串lastName){
this.lastName.set(lastName);
}
公共StringProperty lastNameProperty(){
返回姓氏;
}
}
因此,我们的目标是删除红色列,而不是让“First Name”列占用额外的空间(而不将“Last Name”超出边界) 这是否可能,而不诉诸昂贵的宽度计算
编辑:虽然我的示例使用了
表视图中的第一列,但我希望它适用于我选择的任何列,无论表视图有多少列。如果您不想更改其他列的宽度,这可能是一种解决方案
在tableView和列声明之后包含此项
更新:抱歉,没有注意到问题的最后一行。(关于计算)。因此,如果不适合您,请放弃此解决方案。
TableColumn<?, ?> columnToResize = colFirstName;
tableView.widthProperty().addListener((obs, old, width) -> {
double otherColsWidth = tableView.getColumns().stream().filter(tc -> tc != columnToResize).mapToDouble(tc -> tc.getWidth()).sum();
double padding = tableView.getPadding().getLeft() + tableView.getPadding().getRight();
columnToResize.setPrefWidth(width.doubleValue() - otherColsWidth - padding);
});
TableColumn columnToResize=colFirstName;
tableView.widthProperty().addListener((obs,旧,宽度)->{
double otherColsWidth=tableView.getColumns().stream().filter(tc->tc!=columnToResize).mapToDouble(tc->tc.getWidth()).sum();
双重填充=tableView.getPadding().getLeft()+tableView.getPadding().getRight();
columnToResize.setPrefWidth(width.doubleValue()-otherColsWidth-padding);
});
更新2:
如果您想在调整其他列的大小时更灵活地调整hgrow列的大小,下面是一个快速演示。请注意,调整hgrow列的大小本身没有特定的代码,因为这取决于您如何处理这种情况
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TableColumnGrow extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
VBox root = new VBox(10);
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(10));
HGrowTableView<Person> tableView = new HGrowTableView<>();
TableColumn<Person, String> colFirstName = new HGrowTableColumn<>("First Name");
TableColumn<Person, String> colLastName = new HGrowTableColumn<>("Last Name");
colFirstName.setCellValueFactory(tf -> tf.getValue().firstNameProperty());
colLastName.setCellValueFactory(tf -> tf.getValue().lastNameProperty());
tableView.setColumnToResize(colLastName);
tableView.getColumns().addAll(colFirstName, colLastName);
tableView.getItems().addAll(
new Person("Martin", "Brody"),
new Person("Matt", "Hooper"),
new Person("Sam", "Quint")
);
root.getChildren().add(tableView);
// Show the stage
primaryStage.setScene(new Scene(root));
primaryStage.setTitle("TableColumnGrow Sample");
primaryStage.show();
}
/**
* Custom Table View
*
* @param <S>
*/
class HGrowTableView<S> extends TableView<S> {
TableColumn<?, ?> columnToResize;
ChangeListener<Number> tableWidthListener = (obs, old, width) -> {
double otherColsWidth = getColumns().stream().filter(tc -> tc != columnToResize).mapToDouble(tc -> tc.getWidth()).sum();
double padding = getPadding().getLeft() + getPadding().getRight();
columnToResize.setPrefWidth(width.doubleValue() - otherColsWidth - padding);
};
public void setColumnToResize(TableColumn<?, ?> columnToResize) {
widthProperty().removeListener(tableWidthListener); // Ensuring to remove any previous listener
this.columnToResize = columnToResize;
if (this.columnToResize != null) {
widthProperty().addListener(tableWidthListener);
}
}
public TableColumn<?, ?> getColumnToResize() {
return columnToResize;
}
}
/**
* Custom TableColumn
*
* @param <S>
* @param <T>
*/
class HGrowTableColumn<S, T> extends TableColumn<S, T> {
public HGrowTableColumn(String title) {
super(title);
init();
}
private void init() {
widthProperty().addListener((obs, old, width) -> {
if (getTableView() instanceof HGrowTableView) {
TableColumn<?, ?> columnToResize = ((HGrowTableView) getTableView()).getColumnToResize();
if (columnToResize != null && HGrowTableColumn.this != columnToResize) {
double diff = width.doubleValue() - old.doubleValue();
columnToResize.setPrefWidth(columnToResize.getWidth() - diff);
}
}
});
}
}
class Person {
private final StringProperty firstName = new SimpleStringProperty();
private final StringProperty lastName = new SimpleStringProperty();
public Person(String firstName, String lastName) {
this.firstName.set(firstName);
this.lastName.set(lastName);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String firstName) {
this.firstName.set(firstName);
}
public StringProperty firstNameProperty() {
return firstName;
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String lastName) {
this.lastName.set(lastName);
}
public StringProperty lastNameProperty() {
return lastName;
}
}
}
导入javafx.application.application;
导入javafx.beans.property.SimpleStringProperty;
导入javafx.beans.property.StringProperty;
导入javafx.beans.value.ChangeListener;
导入javafx.geometry.Insets;
导入javafx.geometry.Pos;
导入javafx.scene.scene;
导入javafx.scene.control.TableColumn;
导入javafx.scene.control.TableView;
导入javafx.scene.layout.VBox;
导入javafx.stage.stage;
公共类TableColumnGrow扩展了应用程序{
公共静态void main(字符串[]args){
发射(args);
}
@凌驾
公共无效开始(阶段primaryStage){
VBox根=新的VBox(10);
根部设置对齐(位置中心);
根。设置填充(新插图(10));
HGrowTableView tableView=新建HGrowTableView();
TableColumn colFirstName=新的HGrowTableColumn(“名字”);
TableColumn colLastName=新的HGrowTableColumn(“姓氏”);
colFirstName.setCellValueFactory(tf->tf.getValue().firstNameProperty());
colLastName.setCellValueFactory(tf->tf.getValue().lastNameProperty());
tableView.setColumnToResize(colLastName);
tableView.getColumns().addAll(colFirstName、colLastName);
tableView.getItems().addAll(
新人(“马丁”、“布罗迪”),
新人(“马特”、“胡珀”),
新人(“Sam”、“Quint”)
);
package tmp_table;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class App extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
var people = FXCollections.observableArrayList(
new Person("John Doe", "Male"),
new Person("Jane Doe", "Female")
);
var table = new TableView<Person>(people);
var nameCol = new TableColumn<Person, String>("Name");
var genderCol = new TableColumn<Person, String>("Gender");
nameCol.setCellValueFactory(
cell -> cell.getValue().nameProperty());
genderCol.setCellValueFactory(
cell -> cell.getValue().genderProperty());
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
// this gives name column 70% of table width, the
// CONSTRAINED_RESIZE_POLICY will make the other
// remaining columns fill the table width equally
nameCol.minWidthProperty().bind(
table.widthProperty().multiply(0.7));
table.getColumns().add(nameCol);
table.getColumns().add(genderCol);
var stackPane = new StackPane(table);
StackPane.setAlignment(table, Pos.CENTER);
primaryStage.setScene(new Scene(stackPane, 400, 200));
primaryStage.show();
}
}
class Person {
StringProperty name = new SimpleStringProperty("");
StringProperty gender = new SimpleStringProperty("");
public Person(String name, String gender) {
this.name.set(name);
this.gender.set(gender);
}
public StringProperty nameProperty() {
return name;
}
public StringProperty genderProperty() {
return gender;
}
}
import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
/**
*
* @author blj0011
*/
public class JavaFXTestingGround extends Application{
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
// Simple Interface
VBox root = new VBox(10);
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(10));
TableView<Person> tableView = new TableView<>();
TableColumn<Person, String> colFirstName = new TableColumn<>("First Name");
TableColumn<Person, String> colMiddleName = new TableColumn<>("Last Name");
TableColumn<Person, String> colLastName = new TableColumn<>("Last Name");
colFirstName.setCellValueFactory(tf -> tf.getValue().firstNameProperty());
colLastName.setCellValueFactory(tf -> tf.getValue().lastNameProperty());
colLastName.setCellValueFactory(tf -> tf.getValue().lastNameProperty());
tableView.getColumns().addAll(colFirstName, colMiddleName, colLastName);
tableView.getItems().addAll(
new Person("Martin", "One", "Brody"),
new Person("Matt", "Two", "Hooper"),
new Person("Sam", "Three", "Quint")
);
root.getChildren().add(tableView);
// Show the stage
primaryStage.setScene(new Scene(root));
primaryStage.setTitle("TableColumnGrow Sample");
primaryStage.show();
DoubleProperty width = new SimpleDoubleProperty();
width.bind(colMiddleName.widthProperty().add(colLastName.widthProperty()));
width.addListener((ov, t, t1) -> {
colFirstName.setPrefWidth(tableView.getWidth() - 5 - t1.doubleValue());
});
colFirstName.setPrefWidth(tableView.getWidth() - 5 - width.doubleValue());
colFirstName.setResizable(false);
tableView.widthProperty().addListener((ov, t, t1) -> {
colFirstName.setPrefWidth(tableView.getWidth() - 5 - width.doubleValue());
});
}
}
class Person {
private final StringProperty firstName = new SimpleStringProperty();
private final StringProperty lastName = new SimpleStringProperty();
private final StringProperty middleName = new SimpleStringProperty();
public Person(String firstName, String middleName, String lastName) {
this.firstName.set(firstName);
this.middleName.set(middleName);
this.lastName.set(lastName);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String firstName) {
this.firstName.set(firstName);
}
public StringProperty firstNameProperty() {
return firstName;
}
public String getMiddleName() {
return lastName.get();
}
public void setMiddleName(String lastName) {
this.lastName.set(lastName);
}
public StringProperty middleNameProperty() {
return lastName;
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String lastName) {
this.lastName.set(lastName);
}
public StringProperty lastNameProperty() {
return lastName;
}
}