2017-03-08 4 views
0

Je souhaite remplir un Pane varPane avec un contenu variable. La mise en œuvre ressemble à ceJavaFX: Trigger on Pane non visible/détruit

Pane varPane = new Pane(); 
// .. 

someProperty.addListener((obsv, oldV, newV) -> { 
    varPane.getChildren().clear(); // Remove old Property Pane Content 
    Pane propPane = getNewPane(newV);  // Get new content 
    varPane.getChildren().add(propPane); // add Content 
}); 

Le volet est généré comme:

public Pane getNewPane(Object newV){ 
     Pane myPane = new Pane(); 

     // Add dummy Content 
     myPane.getChildren().add(new Label(newV.toString())) 

     // Here I need some listener 
     // somthing like [not working]: 
     myPane.setOnClosed(System.out.println("Pane closed: " + newV.toString()); 

     return myPane; 
} 

Comme indiqué plus haut, je dois effectuer un nettoyage après le volet n'est plus utilisé. Cependant, je ne pouvais pas trouver de manière correcte de mettre en œuvre un tel auditeur.

L'auditeur doit être déclenchée si:

  • le contenu de varPane est changé et l'ancien volet n'est plus visible, OU
  • si varPane est détruit (par exemple sur Platform.exit())

Je pourrais exiger que sur ces événements une fonction soit appelée pour le nettoyage. Cependant, je pense que ce serait plus sûr, si le volet détecte de tels événements par lui-même.

Répondre

1

Notez d'abord que varPane.getChildren().removeAll() ne fait pas ce que vous pensez. Vous avez besoin

varPane.getChildren().clear(); 

Vous pouvez vérifier si parentProperty() modifications null du volet:

myPane.parentProperty().addListener((obs, oldParent, newParent) -> { 
    if (newParent == null) { 
     System.out.println("Pane closed: " + newV); 
    } 
}); 

Vérification si la fenêtre contenant le volet est caché (fermé) est beaucoup plus difficile. Vous pouvez créer la chaîne suivante d'auditeurs (essentiellement l'écoute afin d'auditeur showingProperty() de la fenêtre de windowProperty() le sceneProperty() du volet afin d'écouter la scène):

ChangeListener<Boolean> showingListener = (obs, wasShowing, isNowShowing) -> { 
    if (! isNowShowing) { 
     System.out.println("Window containing "+newV+" hidden"); 
    } 
}; 
ChangeListener<Window> windowListener = (obs, oldWin, newWin) -> { 
    if (oldWin != null) { 
     oldWin.showingProperty().removeListener(showingListener); 
    } 
    if (newWin != null) { 
     newWin.showingProperty().addListener(showingListener); 
    } 
}; 
ChangeListener<Scene> sceneListener = (obs, oldScene, newScene) -> { 
    if (oldScene != null) { 
     oldScene.windowProperty().removeListener(windowListener); 
     if (oldScene.getWindow() != null) { 
      oldScene.getWindow().showingProperty().removeListener(showingListener); 
     } 
    } 
    if (newScene != null) { 
     newScene.windowProperty().addListener(windowListener); 
     if (newScene.getWindow() != null) { 
      newScene.getWindow().showingProperty().addListener(showingListener); 
     } 
    } 
}; 
myPane.sceneProperty().addListener(sceneListener); 

Vous pouvez préférer utiliser un cadre de fixations, telles comme celui qui fait partie de ReactFX. En utilisant ReactFX, vous pouvez couvrir les deux cas avec

EventStreams.changesOf(Val 
    .flatMap(myPane.sceneProperty(), Scene::windowProperty) 
    .flatMap(Window::showingProperty) 
    .orElseConst(false)) 
    .filter(c -> ! c.getNewValue()) 
    .observe(v -> System.out.println("Pane closed: "+newV));