简体   繁体   中英

javaFX event when objects are rendered

I'd like to get noticed by an event when all the objects in the Scene/Stage are displayed. This sounds like JavaFX doesn't provide this feature. Am I Right ?

I explain why:

I have to update other objects of the scene based on a TableView scroll position. Hence, I'm looking up the VirtualScrollBar of the TableView by using:

tableView.lookupAll(".scroll-bar")

which returns the desired ScrollBar only after TableView is actually rendered. Null in "initialize" block.

Architecture: I'm using a common frame - I'd say - containing an empty Pane updated runtime with actual content given the page I'd like to show. Hence I know when the content is updated, but most of the time before the TableView is rendered, which prevents me to get the ScrollBar reference.

The TableView is part of a "page" and is added to the content Pane, no update on the stage itself.

I'm using Oracle JDK8.

Do you have any clue where I can sort this out ? Thanks in advance for your help.

You need to use the setOnShown() method of the Stage class to be notified when the Stage is visible. Once it is visible, all the controls have been created. The docs say as follows:

public final void setOnShown(EventHandler<WindowEvent> value)

Sets the value of the property onShown.

Property description:
Called just after the Window is shown.

In order to get an answer:

The only workaround I found now is to add a callback to the items observable list of the table itself which is always after TableView rendering and an instance variable to avoid duplicates:

table.getItems().addListener(new ListChangeListener<T>() {

        @Override
        public void onChanged(Change<? extends T> c) {
            if (tableScrollBar == null){
                tableScrollBar = lookupScrollBar(); 
                tableScrollBar.valueProperty().addListener(new ChangeListener<Number>() {

                    @Override
                    public void changed(ObservableValue<? extends Number> arg0, Number oldValue, Number newValue) {
                        // do my job
                    }
                });
            }
        }
    });

This is no such event available. However, you can override layoutChildren() and trigger all the listeners.

private boolean isRendered = false;
protected void layoutChildren() {
    super.layoutChildren();
    if(!isRendered){
        //This is the first time the node is rendered. Event trigger logic should be here
    }
    isRendered = true;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM