JavaFX TableView父列标签不可见

时间:2017-07-20 08:10:57

标签: java javafx label tableview tablecolumn

我在获取JavaFX TableView快照时遇到问题。我想生成一个表的图像文件而不显示舞台。除了未显示舞台时父列标签消失外,一切正常。

我有常规表格,包含样本人物(姓名,年龄,电子邮件 - >(主要,次要))数据:

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" );

Generated image(1)

如您所见,电子邮件的列标签(&#34;电子邮件&#34;)不可见。

我可以通过展示舞台,拍摄图像并隐藏舞台来解决这个问题:

Scene scene = new Scene( personTable );
stage.setScene( scene );
stage.show();
saveAsPng( personTable, "test2.png" );
stage.close();

Generated image(2)

我的目标是在不显示舞台的情况下生成第二张图片(使用&#34;电子邮件&#34;标签)。

我假设只有与它们相关联的值的列显示了图形,所以我尝试了以下内容,但无济于事:

emailColumn.setGraphic( new Label( "Test" ) );
emailColumn.setVisible( true );
emailColumn.getGraphic().setVisible( true );

saveAsPNG:

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();
    }
}

谢谢!

1 个答案:

答案 0 :(得分:1)

每当您对未添加到Scene的{​​{1}}进行操作时,您都缺少作为脉冲的一部分发生的JavaFX布局计算(应用CSS和布局传递)显示常规场景。

在您的情况下,由于未显示场景,您需要在执行快照之前通过手动触发CSS应用程序和布局传递来强制执行布局。

根据JavaFX JavaDoc,您可以通过调用Stagenode.applyCss()轻松完成此操作:

  

public final void applyCss()

     

如果需要,请将样式应用于此节点及其子节点(如果有)。此方法通常不需要直接调用,但可以与Parent.layout()一起使用,以在下一个脉冲之前调整节点大小,或者如果场景不在舞台中。

     

如果Node的Scene不为null,则无论此Node的CSS状态是否干净,都会将CSS应用于此Node。 CSS样式从此Node的最顶级父级应用,其CSS状态不是clean,这可能会影响其他节点的样式。如果Node不在场景中,则此方法为无操作。场景不必处于舞台中。

     

此方法不会调用Parent.layout()方法。通常,调用者将使用以下操作序列。

node.layout

在您的情况下,这将有效:

parentNode.applyCss();
parentNode.layout();

请注意,如果没有为场景或表设置任何大小,布局将使用其pref大小,因此在为每个列提供pref宽度之前应该很方便(可能你已经在做了)它)。