TableView自动行高调整大小 - JavaFX

时间:2016-04-01 01:13:10

标签: java javafx

如果我的TableView包含TableColumn,请执行以下操作:

private TableColumn<Foo, ObservableList<Foo2>> col;

我可以很好地为我显示一个列表。但是,当该列表的大小增加时,单元格(和行)的大小保持不变,因此我的某些单元格会被切断。如果我手动调整列的大小,表将正确地改变行的高度,它将看起来应该如此。

我是否需要以某种方式将行/单元格的高度绑定到ObservableList的大小,或者是否有更好的方法让表自动调整而无需用户干预?

包含的例子:

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Label;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
import javafx.util.Callback;

public class CellResizing extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {

        GridPane root = new GridPane();
        ObservableList<MyFoo> list = FXCollections.observableArrayList();
        list.add(new MyFoo());
        list.get(0).foosProperty().get().add(new Foo2("First Item"));

        TableView<MyFoo> table = new TableView<MyFoo>();
        TableColumn<MyFoo, ObservableList<Foo2>> col = new TableColumn<MyFoo, ObservableList<Foo2>>("List");
        col.setCellValueFactory(new PropertyValueFactory<MyFoo, ObservableList<Foo2>>("foos"));
        Callback<TableColumn<MyFoo, ObservableList<Foo2>>, TableCell<MyFoo, ObservableList<Foo2>>> toolTipFactory =
                new Callback<TableColumn<MyFoo, ObservableList<Foo2>>, TableCell<MyFoo, ObservableList<Foo2>>>() {
            @Override
            public TableCell<MyFoo, ObservableList<Foo2>> call(final TableColumn<MyFoo, ObservableList<Foo2>> param) {
                final TableCell<MyFoo, ObservableList<Foo2>> cell = new TableCell<MyFoo, ObservableList<Foo2>>() {
                    @Override
                    public void updateItem(ObservableList<Foo2> item, boolean empty) {
                        super.updateItem(item, empty);
                        if (empty || item == null) {
                            setText(null);
                            setTooltip(null);
                        } else {
                            GridPane grid = new GridPane();
                            int modulus;
                            if (item.size() < 4) {
                                modulus = 1;
                            }
                            else if (item.size() < 9) {
                                modulus = 2;
                            }
                            else {
                                modulus = 3;
                            }
                            for (int i = 0; i < item.size(); ++i) {
                                Label label = new Label();
                                label.setText(item.get(i).toString());
                                grid.add(label, i % modulus, (i % item.size()) / modulus);
                            }
                            setGraphic(grid);
                            setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
                        }
                    }
                };
                return cell;
            }
        };
        col.setCellFactory(toolTipFactory);
        table.getColumns().add(col);

        Button button = new Button("Add to list");      
        button.setOnAction(new EventHandler<ActionEvent>() {            
            @Override
            public void handle(ActionEvent event) {
                list.get(0).foosProperty().get().add(new Foo2("Text"));
            }
        });
        table.setItems(list);

        root.add(button, 0, 0);
        root.add(table, 0, 1);
        primaryStage.setScene(new Scene(root, 300, 250));
        primaryStage.show();
    }
}

和类MyFoo + Foo2:

import javafx.beans.property.ListProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;

public class MyFoo {
    private ListProperty<Foo2> foos;

    public MyFoo() {
        foos = new SimpleListProperty<Foo2>(FXCollections.observableArrayList());
    }

    public ListProperty<Foo2> foosProperty() {
        return foos;
    }
}

class Foo2 {
    private StringProperty text;

    public Foo2(String string) {
        text = new SimpleStringProperty(string);
    }

    public StringProperty textProperty() {
        return text;
    }

    @Override
    public String toString() {
        return text.get();
    }

}

2 个答案:

答案 0 :(得分:0)

将textWrapper替换为您的文本Container并添加一个resizing命令,代码正在运行。

textWrapper.textProperty().addListener((ov, o, n) -> {
    final Text t = new Text(n);
    t.applyCss(); 
    final double width = t.getLayoutBounds().getWidth();
    //Set new width here
});

答案 1 :(得分:0)

我通过在observablelist上放置一个失效监听器解决了这个问题,每次列表大小改变时都会调用updateItem。

@Override
public void updateItem(ObservableList<Foo2> item, boolean empty) {
    super.updateItem(item, empty);
    if (empty || item == null) {
        setText(null);
        setTooltip(null);
    } else {
        GridPane grid = new GridPane();
        int modulus;
        if (item.size() < 4) {
            modulus = 1;
        }
        else if (item.size() < 9) {
            modulus = 2;
        }
        else {
            modulus = 3;
        }
        for (int i = 0; i < item.size(); ++i) {
            Label label = new Label();
            label.setText(item.get(i).toString());
            grid.add(label, i % modulus, (i % item.size()) / modulus);
        }
        item.addListener(new InvalidationListener() {
            @Override
            public void invalidated(Observable observable) {
                updateItem(item, empty);
            }
        });
        setGraphic(grid);
        setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
    }
}