splitpane - Wechseln auf anderen Split erkennen

Joob

Top Contributor
Ich habe eine Splitpane in dem mehrere Anchorpanes sind.

Ich möchte nun erkennen wenn ein Anchorpane verlassen wird.
Ich habe bereits einen FocusListener auf das Anchorpane gelegt, aber der löst nicht aus.

Hat jemand eine Idee wie ich das anfassen soll.
Muss ich das im Splittpane erkennen und dann den Controller des Anchorpanes ansprechen ?
Das wäre nicht so schön, denn es geht darum nach dem Focusverlust im Anchorpane ggf. zu speichern.

Der Focuslistener ist standard, funktionier bei nodes ja auch gut, aber bei Containern scheint das nicht der richtige Weg zu sein.

Java:
        anchorwordadapter.focusedProperty().addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> {
            focusState(newValue);
        });
 
Ich habe eine Splitpane in dem mehrere Anchorpanes sind.

Ich möchte nun erkennen wenn ein Anchorpane verlassen wird.
Ich habe bereits einen FocusListener auf das Anchorpane gelegt, aber der löst nicht aus.

Hat jemand eine Idee wie ich das anfassen soll.
Muss ich das im Splittpane erkennen und dann den Controller des Anchorpanes ansprechen ?
Das wäre nicht so schön, denn es geht darum nach dem Focusverlust im Anchorpane ggf. zu speichern.

Der Focuslistener ist standard, funktionier bei nodes ja auch gut, aber bei Containern scheint das nicht der richtige Weg zu sein.

Java:
        anchorwordadapter.focusedProperty().addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> {
            focusState(newValue);
        });
Ich habs grad selbst getestet, aus irgendeinem Grund geht es tatsächlich nicht. Kannst du eventuell sagen was du vor hast? Willst du wirklich beim verlassen der AnchorPane ein Event abgefeuert haben? Oder willst du beim Verlassen des MouseCursors ein Event haben? Vielleicht können wir das auch anders vorgehen.
 
Ich habe in jedem Split einen Anchorpane.
Darin wird ein Datensatz dargestellt.
Ich würde gerne feststellen wann der AnchorPane verlassen wird um wenn es Änderungen am Datensatz gibt, diesen zu speichern.

Wenn das klappen würde könnte ich alle Funktionalität in dem Controller belassen und hätte einen übersichtlichen Controller.

Ich habe das Gefühl das das Problem mit FocusTransversal zu lösen ist, aber meine Versuche haben zu nichts geführt.
 
Ich habe in jedem Split einen Anchorpane.
Darin wird ein Datensatz dargestellt.
Ich würde gerne feststellen wann der AnchorPane verlassen wird um wenn es Änderungen am Datensatz gibt, diesen zu speichern.

Wenn das klappen würde könnte ich alle Funktionalität in dem Controller belassen und hätte einen übersichtlichen Controller.

Ich habe das Gefühl das das Problem mit FocusTransversal zu lösen ist, aber meine Versuche haben zu nichts geführt.
Das heißt wenn du mit dem Mousezeiger weg bist, kannst du auch überprüfen ob die Daten angepasst wurden oder?
 
Ein einfacher MouseListener auf Enter- und Exit-Events auf den beiden Panes, sollte das lösen können, oder?
 
Also ich halte paar Ideen für problematisch:
Nur weil die Maus das Fenster verlässt muss der Focus sich nicht verändert haben. Jemand erfasst Daten mit der Tastatur, kommt gegen die Maus und der Mauszeiger verlässt das Fenster oder die Anchor Pane ...

Es gibt wohl unter Linux so eine Einstellung, dass der Focus automatisch der Maus folgt, aber in der Praxis ist dem ja in der Regel nicht so. Und vor allem: die Maus ist weg aber der User ändert weiter ...

Wenn das mit dem Focus Verlust nicht klappt, dann wäre meine Idee eine Prüfung des Focus Eingangs. Dann gibt es eine kleine Instanz eines FocusWächters dem man den Wechsel des Focus mitteilen kann, der also die Events bekommt. Elemente können zu einer Gruppe hinzu gefügt werden. Und bei jedem Wechsel kann dann eine Aktion ausgelöst werden, wenn eine Gruppe den Focus verliert.

Konnte ich die Idee halbwegs rüber bringen? Die Lösung basiert also auf dem bekommen des Focus bei anderen Controls.

Damit liegt die Steuerung rein in der App. Der Focus in der App ist entscheidend und der Benutzer kann z.B. Daten aus einer anderen Applikation holen. Einzugebende Daten kommen per Email und der Benutzer wechselt immer hin und her z.B. für Copy and Paste.

Und die Lösung baut keine Abhängigkeit zwischen den Komponenten ein. Die einzelnen Inhalte müssen sich nicht kennen. Sie müssen halt nur diesen FocusWächter kennen und bedienen.
 
Die Sache mit dem Mauszeiger ist hier nicht hilfreich, denn ich kann auch mit der Tabtaste über die Felder gehen.
Dann bekommt der Mauszeiger das nicht mit.

Auch deine Idee hinsichtlich des getFocus ist nicht komplett hilfreich, denn beim letzten Verlassen wird dieser ja nicht ausgelöst.

Ich versuche nun den gesamten Sperr- und Speichermechanismus im Lade und Entladevorgang unterzubringen. Ich wollte heute anfangen bin mal gespannt was da wieder für Probleme auftauchen.
 
Die Sache mit dem Mauszeiger ist hier nicht hilfreich, denn ich kann auch mit der Tabtaste über die Felder gehen.
Dann bekommt der Mauszeiger das nicht mit.

Auch deine Idee hinsichtlich des getFocus ist nicht komplett hilfreich, denn beim letzten Verlassen wird dieser ja nicht ausgelöst.

Ich versuche nun den gesamten Sperr- und Speichermechanismus im Lade und Entladevorgang unterzubringen. Ich wollte heute anfangen bin mal gespannt was da wieder für Probleme auftauchen.
Wie navigierst du über Tab von einem Pane zum Anderen? Oder ist das jetzt eine Idee die noch Entwickelt wird?
 
Auch deine Idee hinsichtlich des getFocus ist nicht komplett hilfreich, denn beim letzten Verlassen wird dieser ja nicht ausgelöst.
Also ich habe das etwas mehr getestet und generell scheint das aber durchaus zu funktionieren.

Aber das ist zu kompliziert gedacht. Wenn Du bei den Controls statisch bist, dann reicht evtl. schon sowas in der Art aus:
Java:
package helloworld;

import javafx.scene.Node;
import javafx.scene.Parent;

import java.util.HashSet;
import java.util.Set;

public class FocusChecker {
    boolean inside = false;

    Set<Node> nodes = new HashSet<>();
    public FocusChecker(final Node parent) {
        addNodes(parent);
    }

    protected void addNodes(final Node node) {
        nodes.add(node);
        node.focusedProperty().addListener((observable, left, joined) -> {
            if (inside && left) {
                inside = false;
            } else if (!inside && joined) {
                inside = true;
            }
            System.out.println("inside: " + inside);
        });

        if (node instanceof Parent) {
            Parent parent = (Parent) node;
            parent.getChildrenUnmodifiable().forEach(this::addNodes);
        }
    }
}

Das kannst Du einfach für eine pane initialisieren. Bei dem inside umsetzen muss natürlich noch weitere Funktionalität folgen, denn das Problem ist, dass er bei jedem Wechsel inside einmal auf false und wieder auf true setzt. Daher bauen wir einen Timer ein, der erst nach paar ms auslöst - dann haben wir entweder schon wieder das Join Event vom anderen Control bekommen oder der FOcus ist wirklich weg.

Ansteuerung des Timers:
- Bei jedem Durchlauf dieses ChangeListeners wird der Timer, so er gestartet wurde, gestoppt.
- Beim Umsetzen von inside auf false wird dieser gestartet Einmalige Ausführung nach x ms.)
- Der Timer führt dann ein Runnable aus, das der Instanz natürlich noch mit übergeben werden muss. Das könnte dann Dein Speichern sein. Das gehört aber nicht in so eine Klasse.


Was man noch schauen kann, ob man den Parent Element noch einen EventListener unterschieben kann bezüglich Hinzufügen / Entfernen von Children. So dies möglich ist, dann könnte man das sogar universell als FocusListenerControl bauen, das man nur einem Parent zuordnen muss. Beim Zuzordnen setzt er die entsprechenden Listeners und wäre dann immer up to date und könnte Events für Focus kommt in den Parent und Parent verliert Focus generieren... Vielleicht baue ich später noch einmal etwas mehr daran rum, aber mir ging es erst einmal um eine Art Proof Of Concept und das funktioniert vom Prinzip her schon ...
 
Wenn ich sowas bauen würde - wie sollte es denn dann aussehen?
Eigentlich wäre es doch gut, wenn man ein FocusAwarePane hat. Aber da hätte man dann halt dieses Pane und dann dadrin in der Regel ein weiteres Pane. Aber das dürfte ja vom Aufbau her nichts machen.

Das ist vom Konzept her besser als die Idee eines Controls, welches den übergeordneten Parent focus aware macht, oder?

Was die Veränderung der Hierarchie angeht (Ein offener Punkt vom letzten Post) sollte dies ja kein Thema sein, da ein Parent seine Children ja in Observable Lists hat. Änderungen sollte man darüber also mitbekommen können.
 
Hallo,

das mit der Pane hatte ich gestern auch probiert, damit bin ich aber nicht weitergekommen.

Ich habs aber jetzt.
Ich führe eine Miniliste mit den Controllern beim Initialisieren von Splitpane.

Bei erneutem initialisieren gehe ich die Liste durch und mache alle unlocks und safes.
Dann Liste leeren und beim Initialisieren füllen.

Wenn das Fenster unerwartet verlassen wird, noch ein bearbeiten im onRequest.

Scheint zu funktionieren und ist auch übersichtlich.
 

Zurück
Oben