Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

JavaFX's TableView has a placeholder property that is basically a Node that gets displayed in the TableView whenever it is empty. If this property is set to null (its default value), it appears as a Label or some other text based Node that says "There is no content in the table."

But if there are any rows of data in the table, then the placeholder Node disappears and the entire vertical space in the TableView gets filled with rows, including empty rows if there isn't enough data to fill the whole table.

These empty rows are what I want, even when the table is empty. In other words, I don't want to use the placeholder at all. Does anyone know how I can do this?

I'd rather not do something kludgey like put a empty-looking row in the TableView whenever it's supposed to be actually empty.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
190 views
Welcome To Ask or Share your Answers For Others

1 Answer

I think I found a solution. It is definitely not nice, since it is accessing the API in a not wanted way, and I'm probably also making undesired use of the visibleProperty, but here you go:

You can try to hack the TableViewSkin. Basically do this to retrieve a hacked Skin:

public class ModifiedTableView<E> extends TableView<E> {
    @Override
    protected Skin<?> createDefaultSkin() {
        final TableViewSkin<E> skin = new TableViewSkin<E>(this) {
          // override method here
        }
        // modifiy skin here
        return skin;
   }
}

For the TableViewSkin you then need to override following method:

@Override
protected VirtualFlow<TableRow<E>> createVirtualFlow() {
    final VirtualFlow<TableRow<E>> flow = new VirtualFlow<TableRow<E>>();
    // make the 'scroll-region' always visible:
    flow.visibleProperty().addListener((invalidation) -> {
        flow.setVisible(true);
    });
    return flow;
}

And for the skin using reflection stop showing the placeholder:

final Field privateFieldPlaceholderRegion = TableViewSkinBase.class.getDeclaredField("placeholderRegion");
privateFieldPlaceholderRegion.setAccessible(true);
final StackPane placeholderRegion = (StackPane) privateFieldPlaceholderRegion.get(skin);

// make the 'placeholder' never visible:
placeholderRegion.visibleProperty().addListener((invalidation) -> {
    placeholderRegion.setVisible(false);
});

Maybe you can change the visibility of the flow in the same method to make the code shorter... But I think you get the concept


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...