2016-05-03 10 views
4

Ich erstelle ein Fenstermenü für JavaFX, ähnlich dem Standard "Fenster" -Menü auf OS X. Dieses Menü enthält eine Liste von Fenstern für die Anwendung und verwendet ein Häkchen, um den aktuell fokussierten anzuzeigen ein.Benachrichtigung erhalten, wenn Fokusstufe geändert wird

Ich erhalte die Liste aller Fenster von

StageHelper.getStages() 

die mir ein ObservableList gibt automatisch entfernt oder neu erstellten Fenster zu reagieren. Was übrig bleibt, ist den Menüpunkt mit dem aktuell fokussierten Fenster zu markieren. Ich möchte nicht aktiv nach der fokussierten Phase suchen, da ich benachrichtigt werden muss, sobald sich die fokussierte Phase ändert.

Meine aktuelle Idee wäre es, jedem erstellten Stadium einen Fokus-Listener hinzuzufügen, aber ich frage mich, ob da noch etwas anderes ist. Gibt es vielleicht eine Hilfsklasse, die eine beobachtbare Eigenschaft auf der aktuell fokussierten Stufe hält?

+0

Abgesehen: 'StageHelper' private API ist und es ist sehr dringend empfohlen, es nicht zu benutzen (es wird nicht in Java 9, beispielsweise zugänglich sein). –

+0

Ja, ich weiß. Ich suche nach einer java 8 einzigen Lösung. –

Antwort

4

Erstens, ich empfehle sehr nicht nicht-öffentliche API zu verwenden. Es ist wahrscheinlich besser, wenn Sie eine StageFactory-Klasse erstellen, diese mit Ihrer Primärstufe initialisieren und neue Phasen anfordern. Dann kann es alle Stufen für Sie verfolgen (und kann auch leicht die fokussierte Phase verfolgen).

Wenn Sie die Dinge auf diese Weise tun möchten, erstellen Sie eine ObservableList<Stage> mit einer Extraktorzuordnung zu focusedProperty, und binden Sie ihren Inhalt an Ihre vorhandene Liste von Stufen. In der neuen Liste werden dann Aktualisierungen ausgelöst, wenn sich fokussierte Eigenschaften ändern.

SSCCE:

import com.sun.javafx.stage.StageHelper; 

import javafx.application.Application; 
import javafx.beans.Observable; 
import javafx.beans.binding.Bindings; 
import javafx.collections.FXCollections; 
import javafx.collections.ListChangeListener.Change; 
import javafx.collections.ObservableList; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.Label; 
import javafx.scene.layout.BorderPane; 
import javafx.scene.layout.StackPane; 
import javafx.stage.Stage; 

public class TrackFocusedStage extends Application { 

    int stageCount = 1 ; 
    @Override 
    public void start(Stage primaryStage) { 
     ObservableList<Stage> stages = FXCollections.observableArrayList(stage -> new Observable[] {stage.focusedProperty()}); 
     Bindings.bindContent(stages, StageHelper.getStages()); 
     Label label = new Label(); 
     stages.addListener((Change <? extends Stage> c) -> 
      label.setText(
        stages.stream() 
        .filter(Stage::isFocused) 
        .findAny() 
        .map(Stage::getTitle) 
        .orElse(""))); 

     Button newStageButton = new Button("New Window"); 
     newStageButton.setOnAction(e -> newStage()); 
     Scene scene = new Scene(new BorderPane(new StackPane(newStageButton), label, null, null, null), 300, 180); 
     primaryStage.setScene(scene); 
     primaryStage.setTitle("Primary"); 
     primaryStage.show(); 
    } 

    private void newStage() { 
     Stage stage = new Stage(); 
     stage.setTitle("Window "+(++stageCount)); 
     Button close = new Button("Close"); 
     close.setOnAction(e -> stage.hide()); 
     stage.setScene(new Scene(new StackPane(close), 300, 80)); 
     stage.show(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 
Verwandte Themen