JavaFX TableView 父列标签不可见
JavaFX TableView parent column label not visible
我在获取 JavaFX TableView 的快照时遇到问题。我想在不显示舞台的情况下生成 table 的图像文件。一切正常,除了在未显示舞台时父列标签消失。
我有常规 table 样本人物(姓名、年龄、电子邮件->(主要、次要))数据:
TableView<Person> personTable = new TableView<>();
TableColumn<Person, String> nameColumn = new TableColumn<>( "Name" );
TableColumn<Person, Integer> ageColumn = new TableColumn<>( "Age" );
TableColumn<Person, String> emailColumn = new TableColumn<>( "Email" );
TableColumn<Person, String> primaryEmailColumn = new TableColumn<>( "Primary" );
TableColumn<Person, String> secondaryEmailColumn = new TableColumn<>( "Secondary" );
nameColumn.setCellValueFactory( cellDataFeatures -> cellDataFeatures.getValue().nameProperty() );
ageColumn.setCellValueFactory( cellDataFeatures -> cellDataFeatures.getValue().ageProperty().asObject() );
primaryEmailColumn.setCellValueFactory( cellDataFeatures -> cellDataFeatures.getValue().primaryEmailProperty() );
secondaryEmailColumn.setCellValueFactory( cellDataFeatures -> cellDataFeatures.getValue().secondaryEmailProperty() );
emailColumn.getColumns().addAll( primaryEmailColumn, secondaryEmailColumn );
personTable.getColumns().addAll( nameColumn, ageColumn, emailColumn );
personTable.setItems( generatePersonList() );
正在生成图像文件:
Scene scene = new Scene( personTable );
saveAsPng( personTable, "test2.png" );
如您所见,电子邮件的列标签 ("Email") 不可见。
我可以通过显示舞台、拍摄图像和隐藏舞台来解决这个问题:
Scene scene = new Scene( personTable );
stage.setScene( scene );
stage.show();
saveAsPng( personTable, "test2.png" );
stage.close();
我的目标是在不显示舞台的情况下生成第二张图片(带有 "Email" 标签)。
我假设只有具有关联值的列才会显示图形,所以我尝试了以下方法,但无济于事:
emailColumn.setGraphic( new Label( "Test" ) );
emailColumn.setVisible( true );
emailColumn.getGraphic().setVisible( true );
另存为 PNG:
private void saveAsPng(Parent container, String path)
{
File file = new File(path);
WritableImage img = container.snapshot( null, null );
RenderedImage renderedImage = SwingFXUtils.fromFXImage(img, null);
try {
ImageIO.write(renderedImage,"png", file);
}
catch (Exception e) {
e.printStackTrace();
}
}
谢谢!
每当您对未添加到 Stage
的 Scene
执行操作时,您都会错过发生的 JavaFX 布局计算(应用 CSS 和布局传递)在显示常规场景时作为脉冲的一部分。
在您的情况下,由于场景未显示,您需要在执行快照之前通过手动触发 CSS 应用程序和布局通道来实际强制布局。
根据 JavaFX JavaDoc,您可以通过调用 node.applyCss()
和 node.layout
轻松做到这一点:
public final void applyCss()
If required, apply styles to this Node and its children, if any. This method does not normally need to be invoked directly but may be used in conjunction with Parent.layout() to size a Node before the next pulse, or if the Scene is not in a Stage.
Provided that the Node's Scene is not null, CSS is applied to this Node regardless of whether this Node's CSS state is clean. CSS styles are applied from the top‑most parent of this Node whose CSS state is other than clean, which may affect the styling of other nodes. This method is a no-op if the Node is not in a Scene. The Scene does not have to be in a Stage.
This method does not invoke the Parent.layout() method. Typically, the caller will use the following sequence of operations.
parentNode.applyCss();
parentNode.layout();
在你的情况下,这会起作用:
Scene scene = new Scene( personTable );
personTable.applyCss();
personTable.layout();
saveAsPng( personTable, "test2.png" );
请注意,如果您没有为场景设置任何大小,也没有为 table 设置任何大小,布局将使用其 pref 大小,因此在之前为每个列指定一个 pref 宽度应该很方便(可能你已经在做了)。
我在获取 JavaFX TableView 的快照时遇到问题。我想在不显示舞台的情况下生成 table 的图像文件。一切正常,除了在未显示舞台时父列标签消失。
我有常规 table 样本人物(姓名、年龄、电子邮件->(主要、次要))数据:
TableView<Person> personTable = new TableView<>();
TableColumn<Person, String> nameColumn = new TableColumn<>( "Name" );
TableColumn<Person, Integer> ageColumn = new TableColumn<>( "Age" );
TableColumn<Person, String> emailColumn = new TableColumn<>( "Email" );
TableColumn<Person, String> primaryEmailColumn = new TableColumn<>( "Primary" );
TableColumn<Person, String> secondaryEmailColumn = new TableColumn<>( "Secondary" );
nameColumn.setCellValueFactory( cellDataFeatures -> cellDataFeatures.getValue().nameProperty() );
ageColumn.setCellValueFactory( cellDataFeatures -> cellDataFeatures.getValue().ageProperty().asObject() );
primaryEmailColumn.setCellValueFactory( cellDataFeatures -> cellDataFeatures.getValue().primaryEmailProperty() );
secondaryEmailColumn.setCellValueFactory( cellDataFeatures -> cellDataFeatures.getValue().secondaryEmailProperty() );
emailColumn.getColumns().addAll( primaryEmailColumn, secondaryEmailColumn );
personTable.getColumns().addAll( nameColumn, ageColumn, emailColumn );
personTable.setItems( generatePersonList() );
正在生成图像文件:
Scene scene = new Scene( personTable );
saveAsPng( personTable, "test2.png" );
如您所见,电子邮件的列标签 ("Email") 不可见。
我可以通过显示舞台、拍摄图像和隐藏舞台来解决这个问题:
Scene scene = new Scene( personTable );
stage.setScene( scene );
stage.show();
saveAsPng( personTable, "test2.png" );
stage.close();
我的目标是在不显示舞台的情况下生成第二张图片(带有 "Email" 标签)。
我假设只有具有关联值的列才会显示图形,所以我尝试了以下方法,但无济于事:
emailColumn.setGraphic( new Label( "Test" ) );
emailColumn.setVisible( true );
emailColumn.getGraphic().setVisible( true );
另存为 PNG:
private void saveAsPng(Parent container, String path)
{
File file = new File(path);
WritableImage img = container.snapshot( null, null );
RenderedImage renderedImage = SwingFXUtils.fromFXImage(img, null);
try {
ImageIO.write(renderedImage,"png", file);
}
catch (Exception e) {
e.printStackTrace();
}
}
谢谢!
每当您对未添加到 Stage
的 Scene
执行操作时,您都会错过发生的 JavaFX 布局计算(应用 CSS 和布局传递)在显示常规场景时作为脉冲的一部分。
在您的情况下,由于场景未显示,您需要在执行快照之前通过手动触发 CSS 应用程序和布局通道来实际强制布局。
根据 JavaFX JavaDoc,您可以通过调用 node.applyCss()
和 node.layout
轻松做到这一点:
public final void applyCss()
If required, apply styles to this Node and its children, if any. This method does not normally need to be invoked directly but may be used in conjunction with Parent.layout() to size a Node before the next pulse, or if the Scene is not in a Stage.
Provided that the Node's Scene is not null, CSS is applied to this Node regardless of whether this Node's CSS state is clean. CSS styles are applied from the top‑most parent of this Node whose CSS state is other than clean, which may affect the styling of other nodes. This method is a no-op if the Node is not in a Scene. The Scene does not have to be in a Stage.
This method does not invoke the Parent.layout() method. Typically, the caller will use the following sequence of operations.
parentNode.applyCss(); parentNode.layout();
在你的情况下,这会起作用:
Scene scene = new Scene( personTable );
personTable.applyCss();
personTable.layout();
saveAsPng( personTable, "test2.png" );
请注意,如果您没有为场景设置任何大小,也没有为 table 设置任何大小,布局将使用其 pref 大小,因此在之前为每个列指定一个 pref 宽度应该很方便(可能你已经在做了)。