在JavaFx-14 resizeColumnToFitContent method中,自动调整列的大小以适应标头和列数据的大小的方法已经建立。
总的来说,这是可行的,至少对于简单的列是这样,但是当我尝试使用cellFactory设置为CheckBoxTableCell.forTableColumn的列时,或者当我试图创建自己的TableCell (就像对过滤的组合框一样)时,我得到的只是默认宽度( 80),它与标题宽度或数据宽度无关。
显然,在CheckBoxTableCell的情况下,单元格几乎总是比标题小,但是即使在这里,列标题也会被截断。在前两列下面的图像中,似乎像预期的那样工作,但是职业列同时截断了头文本和行数据文本,而在CheckBoxTableCell的情况下,只有头(应该读为“启用测试”)被截断。
我假设简单的TableCell所使用的默认TableColumn有一些东西我需要添加到显式单元格中,尽管它必须看看我如何将它添加到.forTableColumn生成的TableCell中。
用复选框列显示问题的代码(在scala中,对不起,我的Java最近太生疏了):-
import scalafx.application.JFXApp3
import scalafx.application.JFXApp3.PrimaryStage
import scalafx.scene.Scene
import scalafx.scene.control.TableView
import scalafx.scene.control.TableColumn
import scalafx.scene.control.cell.CheckBoxTableCell
import scalafx.beans.property.BooleanProperty
import scalafx.beans.value.ObservableValue
import scalafx.collections.ObservableBuffer
import javafx.scene.control.TableColumnBase
import javafx.scene.control.skin.{NestedTableColumnHeader,TableColumnHeader,TableHeaderRow,TableViewSkin}
import scalafx.application.Platform
object TableColumnWidth extends JFXApp3 {
override def start(): Unit = {
stage = new PrimaryStage {
title = "Test Table Column Width Problem"
scene = new Scene {
val ob = ObservableBuffer[TableColumnData]()
val table = new TableView[TableColumnData](ob) {
def createDefaultSkin = new TableViewSkin(this) {
override protected def createTableHeaderRow:TableHeaderRow = {
new TableHeaderRow(this) {
override protected def createRootHeader:NestedTableColumnHeader = {
new NestedTableColumnHeader(null) {
override protected def createTableColumnHeader(col:TableColumnBase[_,_]) = {
if(col == null || col.getColumns.isEmpty || col == getTableColumn) new FormFxTableColumnHeader(col)
else new NestedTableColumnHeader(col)
}
}
}
}
}
}
columns ++= Seq{new TableColumn[TableColumnData,java.lang.Boolean](){
text = "Enabled Test"
cellValueFactory = { c =>
(new BooleanProperty(this,"Enabled",c.value.enabled) {
onChange{ (_,_,newValue) => c.value.enabled = newValue }
}).asInstanceOf[ObservableValue[java.lang.Boolean,java.lang.Boolean]]
}
cellFactory = CheckBoxTableCell.forTableColumn(this)
editable = true
resizable = false
}
}
editable = true
}
root = table
ob ++= Seq(TableColumnData("First",false),
TableColumnData("Second",false))
Platform.runLater(() -> {
val w = table.columns.map { col =>
// To find the TableColumnHeader we can use column.getStyleableNode as suggested by kleopatra on StackOverflow:-
// you get the header from column.getStyleableNode (took a moment, had to check if it's really implemented) – kleopatra Jul 1 at 20:46
col.getStyleableNode() match {
case mtch:FormFxTableColumnHeader => mtch.resizeCol()
case u => col.getWidth()
}
}.sum + 25
// if(width.value > w) {
table.prefWidth = w
table.minWidth = w
table.maxWidth = w
})
sizeToScene()
}
}
}
}
class FormFxTableColumnHeader(tc:TableColumnBase[_,_]) extends TableColumnHeader(tc) {
def resizeCol():Double = {
resizeColumnToFitContent(-1)
// println(s"in resizeCol for ${tc.getText()}, width ${tc.width.value}}")
tc.getWidth()
}
}
class TableColumnData(var name:String,var enabled:Boolean)
这个标题将被截断为“已启用.”
有人对需要什么有什么想法吗?
发布于 2022-10-19 00:25:40
正如注释中已经提到的,我不认为在使用resizeColumnToFitContent
方法时存在任何问题。
下面是用java (FX18)重新编写的示例。它的工作原理是调整表的大小。
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Skin;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumnBase;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.control.skin.NestedTableColumnHeader;
import javafx.scene.control.skin.TableColumnHeader;
import javafx.scene.control.skin.TableHeaderRow;
import javafx.scene.control.skin.TableViewSkin;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class FitTableViewToColumnsDemo extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
ObservableList<Person> persons = FXCollections.observableArrayList();
persons.add(new Person("Bruce Willis", "bruce.willis@disaster.com", "Actor"));
persons.add(new Person("Liz Truss", "liz.truss@gov.uk", "Prime Minister"));
persons.add(new Person("Vincent van Gough", "vincent@sunflower.com", "Artist"));
TableColumn<Person, String> nameCol = new TableColumn<>("Name");
nameCol.setCellValueFactory(param -> param.getValue().nameProperty());
TableColumn<Person, String> emailCol = new TableColumn<>("Email");
emailCol.setCellValueFactory(param -> param.getValue().emailProperty());
TableColumn<Person, Boolean> enabledCol = new TableColumn<>("Enabled Test");
enabledCol.setCellValueFactory(param -> param.getValue().enabledProperty());
enabledCol.setCellFactory(CheckBoxTableCell.forTableColumn(enabledCol));
TableColumn<Person, String> profCol = new TableColumn<>("Profession");
profCol.setCellValueFactory(param -> param.getValue().professionProperty());
TableView<Person> tableView = new TableView<>() {
@Override
protected Skin<?> createDefaultSkin() {
return new MyTableViewSkin(this);
}
};
tableView.getColumns().addAll(nameCol, emailCol, profCol, enabledCol);
tableView.setItems(persons);
VBox root = new VBox();
root.getChildren().addAll(tableView);
VBox.setVgrow(tableView, Priority.ALWAYS);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.setTitle("FX18 FitTableViewToColumnsDemo");
primaryStage.show();
Platform.runLater(() -> {
double totalWidth = tableView.getColumns().stream().map(tc -> {
if (tc.getStyleableNode() instanceof FormFxTableColumnHeader header) {
return header.resizeCol();
} else {
return tc.getWidth();
}
}).mapToDouble(f -> f.doubleValue()).sum();
totalWidth = totalWidth + 25;
tableView.setPrefWidth(totalWidth);
tableView.setMinWidth(totalWidth);
tableView.setMaxWidth(totalWidth);
primaryStage.sizeToScene();
});
}
class MyTableViewSkin extends TableViewSkin<Person> {
public MyTableViewSkin(TableView<Person> tableView) {
super(tableView);
}
@Override
protected TableHeaderRow createTableHeaderRow() {
return new TableHeaderRow(this) {
@Override
protected NestedTableColumnHeader createRootHeader() {
return new NestedTableColumnHeader(null) {
@Override
protected TableColumnHeader createTableColumnHeader(TableColumnBase col) {
if (col == null || col.getColumns().isEmpty() || col == getTableColumn()) {
return new FormFxTableColumnHeader(col);
} else {
return new NestedTableColumnHeader(col);
}
}
};
}
};
}
}
class FormFxTableColumnHeader extends TableColumnHeader {
TableColumnBase tcb;
public FormFxTableColumnHeader(TableColumnBase tc) {
super(tc);
tcb = tc;
}
public double resizeCol() {
resizeColumnToFitContent(-1);
return tcb.getWidth();
}
}
class Person {
private StringProperty name = new SimpleStringProperty();
private StringProperty email = new SimpleStringProperty();
private StringProperty profession = new SimpleStringProperty();
private BooleanProperty enabled = new SimpleBooleanProperty();
public Person(String name1, String email1, String profession1) {
name.set(name1);
email.set(email1);
profession.set(profession1);
}
public StringProperty nameProperty() {
return name;
}
public StringProperty emailProperty() {
return email;
}
public BooleanProperty enabledProperty() {
return enabled;
}
public StringProperty professionProperty() {
return profession;
}
}
}
更新:
如果我将列resizable
属性设置为false
,那么我现在就可以重现这个问题了。我认为这也应该是你身边的问题。
如果要将列设置为可调整大小的false
,我认为可以在声明时删除该设置,并在计算tableView宽度后(以Platform.runLater格式)添加该设置。就像..。
Platform.runLater(() -> {
double totalWidth = tableView.getColumns().stream().map(tc -> {
if (tc.getStyleableNode() instanceof FormFxTableColumnHeader header) {
return header.resizeCol();
} else {
return tc.getWidth();
}
}).mapToDouble(f -> f.doubleValue()).sum();
totalWidth = totalWidth + 25;
tableView.setPrefWidth(totalWidth);
tableView.setMinWidth(totalWidth);
tableView.setMaxWidth(totalWidth);
profCol.setResizable(false); \\ turn off resizable after the width is computed
enabledCol.setResizable(false);
primaryStage.sizeToScene();
});
https://stackoverflow.com/questions/74098105
复制相似问题