Die Bindung einer Eigenschaft text des Labels (in einer FXML-Datei) auf eine IntegerProperty (in einem controller)
Ich habe eine Datenbindung zwischen einem Label in einer FXML-Datei und eine IntegerProperty in den zugehörigen controller. Das problem ist, dass, obwohl das Etikett wird auf den richtigen Wert bei der Initialisierung, es wird nicht aktualisiert, wenn der Wert der Eigenschaft ändert.
FXML-Datei
<?xml version="1.0" encoding="UTF-8"?>
<?import java.net.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<GridPane xmlns:fx="http://javafx.com/fxml"
fx:controller="application.PaneController" minWidth="200">
<Label id="counterLabel" text="${controller.counter}" />
<Button translateX="50" text="Subtract 1"
onAction="#handleStartButtonAction" />
</GridPane>
Controller
package application;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.beans.binding.Bindings;
import javafx.beans.property.*;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
public class PaneController implements Initializable
{
private IntegerProperty counter;
public int getCounter()
{
return counter.get();
}
public void setCounter(int value)
{
counter.set(value);
}
public PaneController()
{
counter = new SimpleIntegerProperty(15);
}
@Override
public void initialize(URL url, ResourceBundle resources)
{
}
@FXML
private void handleStartButtonAction(ActionEvent event)
{
setCounter(getCounter() - 1);
System.out.println(getCounter());
}
}
Erwartung
Jedes mal, wenn ich drücken Sie die "Subtrahieren 1" - Schaltfläche wird der Zähler Dekrementieren um 1, und die counterLabel wird automatisch aktualisiert.
Realität
Den Zähler nicht dekrementiert um 1, aber die counterLabel stecken bleibt bei 15 (der erste Wert).
Frage
Ich war unter dem Eindruck (z.B. aus dieses forum posten), dass das, was ich getan habe, sollte funktionieren. Was bin ich?
InformationsquelleAutor devuxer | 2013-11-06
Du musst angemeldet sein, um einen Kommentar abzugeben.
Benötigen Sie ein JavaFX-spezifischen accessor variableNameEigenschaft an den controller:
EDIT: Mehr details.
Die API-Dokumentation erwähnt nicht so viel über dieses JavaFX - JavaBeans-Architektur. Nur eine Einführung dazu hier ( Verwendung von JavaFX-Properties und Binding ), aber wieder nichts über deren Notwendigkeit.
So können Graben einige source-code! 🙂
Unkompliziert, wir beginnen zu schauen, FXMLLoader code ersten. Wir bemerken Präfix für die Bindung als Ausdruck
Weiter in Zeile 279 FXMLLoader bestimmt
if (isBindingExpression(value))
dann verbindlich, instanziiertBeanAdapter
und bekommt propertyModel:Wenn wir uns in BeanAdapter
#getPropertyModel()
,es die Delegierten
BeanAdapter#get()
nach anfügenString PROPERTY_SUFFIX = "Property";
In der get () - Methode, einfach die get (entweder counterProperty oder getCounter oder isCounter) aufgerufen, durch Reflexion, gibt das Ergebnis zurück. Wenn die get-Methode nicht existiert, wird null zurückgegeben. In anderen Worten, wenn die "counterProperty()" existiert nicht in der JavaBean ist, wird null zurückgegeben, wie in unserem Fall. In diesem Fall ist die Bindung nicht ausgeführt, aufgrund der Aussage
if (propertyModel instanceof Property<?>)
im FXMLLoader. Als ein Ergebnis, keine "counterProperty ()" - Methode keine Bindungen.Was passiert, wenn die get-Methode ist nicht definiert in der Bohne? Wieder aus der
BeanAdapter#get()
code können wir sagen, dass, wenn die "getCounter()" nicht gefunden, wird null zurückgegeben und der Anrufer einfach ignoriert, da keine-op imo.${controller.counterProperty}
. Wenn ich es verlassen, als nur${controller.counter}
es funktioniert. Dank sehr viel!Auch, interessanterweise, schlägt es fehl, wenn ich entfernen Sie die Definitionen zu
getCounter()
undsetCounter()
(und gerade die Arbeit mit dencounter
Feld direkt). Bedeutet das, dass Getter/setter auf die Steuerung verwendet werden, indem der Mechanismus für die Bindung? (Es ist unerwartet, dass ich brauchen würde, um eine getter für die Eigenschaften sowie ein getter/setter für die Wert die Eigenschaft.)Vielen Dank für das update, Uluk! Definitiv hilft, zu verstehen, das system besser. Ich würde ein +1, wenn ich könnte.
Hallo ich danke Ihnen sehr für Ihre Antworten. In meine FXML-Datei in intellij die controller-Schlüsselwort ist, rot zeigt die Fehlermeldung
Cannot resolve symbol 'controller'
. wenn ich es laufen - alles funktioniert gut, obwohl. scheint wie eine intellij-integration scheitern. Weiß jemand wie man dieses Problem beheben?Ich bin nicht auf intellij. So die einzige Vermutung ist, Sie kann vergessen, die "fx" - Präfix, nämlich es sollte "fx:controller".
InformationsquelleAutor Uluk Biy