Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
JavaFXLabel.Text mit bind an DoubleProperty binden
Ich möchte einen Label.Text mit bind an einen DoubleProperty binden. Etwa so:
Java:
class A
public DoubleProperty value = new SimpleDoubleProperty(100.0);
public void addValue() {
value.set(value.get() +10);
}
class B
Label label = new Label();
label.bind(A.value.toString); <-- so gehts aber nicht
A.addValue();
In dem skizzierten Code stimmt ja schon Einiges nicht. Label hat keine bind Methode. Statt dessen gibt es in Controls Properties und Du kannst die Properties binden. Label hat so z.B. ein textProperty.
Dann hast Du einen StringProperty und willst es an eine NumberProperty binden. Das bedeutet, dass Du da konvertieren musst.
Das kannst Du machen mit Hilfe der NumberStringConverter Klasse, die Du z.B. bei bindBidirectional Aufruf mit angeben kannst.
Also etwas wie label.textProperty().bindBidirectional(A.value, new NumberStringConverter); (Im Forum geschrieben also ggf. Tippfehler enthalten).
Bis auf die fehlenden Klammern für den NumberStringConverter() funktioniert es tadellos.
Vielen Dank!
Noch eine Frage: Geht das nur mit einer bidirectionalen Bindung?
Es gibt leider keine bind Methode, die auch einen Converter als Parameter mit nimmt. Wenn es aber wirklich nur in eine Richtung gehen soll, also versehentliches setzen des Textes des Labels nicht die eigene Variable verändern soll, dann kann man sich natürlich eine Lösung bauen, die eine StringProperty bereit stellt. Dann hast hast Du den Aufbau:
Control --bind--> StringProperty <--bind-->DoubleProperty
Das bidirektionale bind hat dann den gewünschten Converter (kann auch selbst geschrieben werden, wenn man spezielles Handling wünscht.
Ich weiss jetzt nicht, ob es da nicht vielleicht sogar schon eine fertige Implementierung gibt, aber das kann ja z.B. eine Utility Methode sein. Etwas wie:
Java:
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.util.converter.NumberStringConverter;
public class BindingUtils {
public static StringProperty stringProperty(DoubleProperty property) {
StringProperty result = new SimpleStringProperty();
result.bindBidirectional(property, new NumberStringConverter());
return result;
}
}
Dann hast Du nur noch einen Aufruf a.la. label.bind(BindingUtils.stringProperty(doubleProperty));
(Das wäre dann etwas, wo ich mir für meinen Code extension methods wünschen würde ... dann wäre das recht schnell nur noch ein doubleProperty.stringProperty() Aufruf ... Aber das gibt es in Java nicht und da es auch Argumente gegen genau diese extrension methods gibt, wird es die wohl auch in Zukunft weiter nicht geben...
Wenn man solche Funktionalität braucht, dann wäre ggf. so eine Lösung interessant:
Java:
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.util.converter.NumberStringConverter;
public class MyDoubleProperty extends SimpleDoubleProperty {
public MyDoubleProperty of(DoubleProperty property) {
MyDoubleProperty result = new MyDoubleProperty();
result.bindBidirectional(property);
return result;
}
public StringProperty stringProperty() {
StringProperty result = new SimpleStringProperty();
result.bindBidirectional(this, new NumberStringConverter());
return result;
}
}
Ist aber nur ein geistiger Schnellschuss - der Name ist natürlich noch lachhaft .. statt "My" wäre da ein "Extended" oder so denkbar.
Ob das so etwas taugt, kann ich nicht einmal sagen. Man kann aber eine neue DoubleProperty erstellen, welche dann diese stringProperty Methode hätte. Und man kann - so man schon eine DoubleProperty irgendwoher hat (kann ja ein anderes Control sein oder so), darauf eine neue Instanz setzen - mittels bindBidirectional hätte man da dann eine Verbindung. Ob das Design gut ist und sowas eine gute Idee ist - da müsste man evtl. noch drüber nachdenken und paar Tests machen. Aber das war halt jetzt so eine Idee, die mir direkt gekommen ist und die ich mal nieder geschrieben habe.