首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >JavaFX TableView调整大小列以配合使用并不总是有效的

JavaFX TableView调整大小列以配合使用并不总是有效的
EN

Stack Overflow用户
提问于 2022-10-17 13:29:45
回答 1查看 73关注 0票数 0

JavaFx-14 resizeColumnToFitContent method中,自动调整列的大小以适应标头和列数据的大小的方法已经建立。

总的来说,这是可行的,至少对于简单的列是这样,但是当我尝试使用cellFactory设置为CheckBoxTableCell.forTableColumn的列时,或者当我试图创建自己的TableCell (就像对过滤的组合框一样)时,我得到的只是默认宽度( 80),它与标题宽度或数据宽度无关。

显然,在CheckBoxTableCell的情况下,单元格几乎总是比标题小,但是即使在这里,列标题也会被截断。在前两列下面的图像中,似乎像预期的那样工作,但是职业列同时截断了头文本和行数据文本,而在CheckBoxTableCell的情况下,只有头(应该读为“启用测试”)被截断。

我假设简单的TableCell所使用的默认TableColumn有一些东西我需要添加到显式单元格中,尽管它必须看看我如何将它添加到.forTableColumn生成的TableCell中。

用复选框列显示问题的代码(在scala中,对不起,我的Java最近太生疏了):-

代码语言:javascript
运行
复制
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)

这个标题将被截断为“已启用.”

有人对需要什么有什么想法吗?

EN

回答 1

Stack Overflow用户

发布于 2022-10-19 00:25:40

正如注释中已经提到的,我不认为在使用resizeColumnToFitContent方法时存在任何问题。

下面是用java (FX18)重新编写的示例。它的工作原理是调整表的大小。

代码语言:javascript
运行
复制
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格式)添加该设置。就像..。

代码语言:javascript
运行
复制
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();
});
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74098105

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档