Last active
August 29, 2015 14:17
-
-
Save james-d/a213d9b768e036e08b6f to your computer and use it in GitHub Desktop.
Demo of JavaBeanPropertyAdapter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.beans.PropertyChangeListener; | |
import java.beans.PropertyChangeSupport; | |
import java.util.ArrayList; | |
import java.util.List; | |
import javafx.application.Application; | |
import javafx.beans.InvalidationListener; | |
import javafx.beans.property.StringProperty; | |
import javafx.beans.property.adapter.JavaBeanStringProperty; | |
import javafx.beans.property.adapter.JavaBeanStringPropertyBuilder; | |
import javafx.beans.value.ChangeListener; | |
import javafx.beans.value.ObservableValue; | |
import javafx.geometry.Insets; | |
import javafx.scene.Scene; | |
import javafx.scene.control.Button; | |
import javafx.scene.control.Label; | |
import javafx.scene.control.TextField; | |
import javafx.scene.layout.GridPane; | |
import javafx.stage.Stage; | |
public class JavaBeanPropertyAdapterTest extends Application { | |
@Override | |
public void start(Stage primaryStage) throws Exception { | |
GridPane root = new GridPane(); | |
root.setPadding(new Insets(12)); | |
root.setHgap(6); | |
root.setVgap(6); | |
root.addRow(0, new Label(), new Label("Plain POJO"), new Label("\"Bound\" POJO"), new Label("Naive property"), new Label("Full property")); | |
PlainPOJO plainPOJO = new PlainPOJO(""); | |
BoundPOJO boundPOJO = new BoundPOJO(""); | |
Label plainPOJOLabel = new Label(); | |
JavaBeanStringProperty plainPOJOAdapter = JavaBeanStringPropertyBuilder.create() | |
.bean(plainPOJO) | |
.name("name") | |
.build(); | |
plainPOJOLabel.textProperty().bind(plainPOJOAdapter); | |
Label boundPOJOLabel = new Label(); | |
JavaBeanStringProperty boundPOJOAdapter = JavaBeanStringPropertyBuilder.create() | |
.bean(boundPOJO) | |
.name("name") | |
.build(); | |
boundPOJOLabel.textProperty().bind(boundPOJOAdapter); | |
StringProperty naiveProperty = new BasicStringProperty() { | |
@Override | |
public boolean firesInvalid() { | |
return false; | |
} | |
}; | |
StringProperty invalidFiringProperty = new BasicStringProperty() { | |
@Override | |
public boolean firesInvalid() { | |
return true; | |
} | |
}; | |
Label naiveBoundLabel = new Label(); | |
naiveBoundLabel.textProperty().bind(naiveProperty); | |
Label fullBoundLabel = new Label(); | |
fullBoundLabel.textProperty().bind(invalidFiringProperty); | |
root.addRow(1, new Label("Value:"), plainPOJOLabel, boundPOJOLabel, naiveBoundLabel, fullBoundLabel); | |
TextField plainTF = new TextField(); | |
plainTF.setOnAction(event -> plainPOJO.setName(plainTF.getText())); | |
TextField boundTF = new TextField(); | |
boundTF.setOnAction(event -> boundPOJO.setName(boundTF.getText())); | |
TextField naiveTF = new TextField(); | |
naiveTF.setOnAction(event -> naiveProperty.set(naiveTF.getText())); | |
TextField fullTF = new TextField(); | |
fullTF.setOnAction(event -> invalidFiringProperty.set(fullTF.getText())); | |
root.addRow(2, new Label("Update:"), plainTF, boundTF, naiveTF, fullTF); | |
Label currentPlainValue = new Label(); | |
Label currentBoundValue = new Label(); | |
Label currentNaiveValue = new Label(); | |
Label currentFullValue = new Label(); | |
Button refreshPlain = new Button("Show and Force Refresh"); | |
refreshPlain.setOnAction(event -> { | |
currentPlainValue.setText(plainPOJOLabel.getText()); | |
plainPOJOLabel.textProperty().unbind(); | |
plainPOJOLabel.textProperty().bind(plainPOJOAdapter); | |
}); | |
Button refreshBound = new Button("Show and Force Refresh"); | |
refreshBound.setOnAction(event -> { | |
currentBoundValue.setText(boundPOJOLabel.getText()); | |
boundPOJOLabel.textProperty().unbind(); | |
boundPOJOLabel.textProperty().bind(boundPOJOAdapter); | |
}); | |
Button refreshNaive = new Button("Show and Force Refresh"); | |
refreshNaive.setOnAction(event -> { | |
currentNaiveValue.setText(naiveBoundLabel.getText()); | |
naiveBoundLabel.textProperty().unbind(); | |
naiveBoundLabel.textProperty().bind(naiveProperty); | |
}); | |
Button refreshFull = new Button("Show and Force Refresh"); | |
refreshFull.setOnAction(event -> { | |
currentFullValue.setText(fullBoundLabel.getText()); | |
fullBoundLabel.textProperty().unbind(); | |
fullBoundLabel.textProperty().bind(invalidFiringProperty); | |
}); | |
root.addRow(3, new Label("Refresh"), refreshPlain, refreshBound, refreshNaive, refreshFull); | |
root.addRow(4, new Label(" "), currentPlainValue, currentBoundValue, currentNaiveValue, currentFullValue); | |
Scene scene = new Scene(root); | |
primaryStage.setScene(scene); | |
primaryStage.show(); | |
} | |
public static abstract class BasicStringProperty extends StringProperty { | |
private final List<ChangeListener<? super String>> changeListeners = new ArrayList<>(); | |
private final List<InvalidationListener> invalidationListeners = new ArrayList<>(); | |
private String value = "" ; | |
@Override | |
public void bind(ObservableValue<? extends String> observable) { | |
// no-op: binding not supported | |
} | |
@Override | |
public void unbind() { | |
// no-op: binding not supported | |
} | |
@Override | |
public boolean isBound() { | |
return false; | |
} | |
@Override | |
public Object getBean() { | |
return null; | |
} | |
@Override | |
public String getName() { | |
return null; | |
} | |
@Override | |
public void addListener(ChangeListener<? super String> listener) { | |
changeListeners.add(listener); | |
} | |
@Override | |
public void removeListener(ChangeListener<? super String> listener) { | |
changeListeners.remove(listener); | |
} | |
@Override | |
public void addListener(InvalidationListener listener) { | |
invalidationListeners.add(listener); | |
} | |
@Override | |
public void removeListener(InvalidationListener listener) { | |
invalidationListeners.remove(listener); | |
} | |
@Override | |
public String get() { | |
return value ; | |
} | |
@Override | |
public void set(String value) { | |
this.value = value ; | |
if (firesInvalid()) { | |
invalidationListeners.forEach(l -> l.invalidated(this)); | |
} | |
} | |
public abstract boolean firesInvalid() ; | |
} | |
public static void main(String[] args) throws NoSuchMethodException { | |
launch(args); | |
} | |
public static class BoundPOJO { | |
private String name ; | |
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); | |
public BoundPOJO(String name) { | |
this.name = name ; | |
} | |
public void addPropertyChangeListener(PropertyChangeListener listener) { | |
this.pcs.addPropertyChangeListener(listener); | |
} | |
public void removePropertyChangeListener(PropertyChangeListener listener) { | |
this.pcs.removePropertyChangeListener(listener); | |
} | |
public String getName() | |
{ | |
return this.name; | |
} | |
public void setName(String name) | |
{ | |
String oldName = this.name ; | |
this.name = name ; | |
pcs.firePropertyChange("name", oldName, name); | |
} | |
} | |
public static class PlainPOJO { | |
private String name ; | |
public PlainPOJO(String name) { | |
this.name = name ; | |
} | |
public String getName() { | |
return name ; | |
} | |
public void setName(String name) { | |
this.name = name ; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment