Matura: Softwareentwicklung & Informationssysteme

5.2. JavaFX Properties & Bindings, Multithreading

Properties

Einfache Properties (abstrakte Klassen):

Erzeugen von Properties über konkrete Klassen (Konstruktor mit maximalen Parametern)

BooleanProperty booleanProperty = new
SimpleBooleanProperty(true, b, this);

DoubleProperty doubleProperty = new
SimpleDoubleProperty(1.5, d, this);

FloatProperty floatProperty = new
SimpleFloatProperty(1.5f, f, this);

IntegerProperty integerProperty = new
SimpleIntegerProperty(123, i, this);

LongProperty longProperty = new
SimpleLongProperty(1234567899l, l, this);

StringProperty stringProperty = new
SimpleStringProperty("hallo", s, this);

Object Properties

ObjectProperty<Image> objectProperty =
new SimpleObjectProperty<>();

Bindings

label.textProperty().bind(myBean.sampleProperty());
label.textProperty().unbind();

Numerische Bindings

DoubleProperty number1 = new SimpleDoubleProperty(1);
DoubleProperty number2 = new SimpleDoubleProperty(2);
DoubleProperty number3 = new SimpleDoubleProperty(3);

NumberBinding calculated = Bindings.add(
number1, Bindings.multiply(number2,number3));

Fluent-API

DoubleProperty number1 = new SimpleDoubleProperty(1);
DoubleProperty number2 = new SimpleDoubleProperty(2);
DoubleProperty number3 = new SimpleDoubleProperty(3);

NumberBinding calculated =
number1.add(number2.multiply(number3));

Low-Level-API

DoubleProperty number1 = new SimpleDoubleProperty(1);
DoubleProperty number2 = new SimpleDoubleProperty(2);
DoubleProperty number3 = new SimpleDoubleProperty(3);
NumberBinding calculated = new DoubleBinding() {
   {
     super.bind(number1, number2, number3);
   }
   @Override
   protected double computeValue() {
     return number1.get() + (number2.get() * number3.get());
   }
};

Bidirektionale Bindings

DoubleProperty number1 = new SimpleDoubleProperty(1);
DoubleProperty number2 = new SimpleDoubleProperty(2);
number2.bindBidirectional(number1);

Object Bindings

Boolean Bindings

BooleanBinding textFieldEntered =
textField.textProperty()
.isNotEmpty()
.and(textField.textProperty().length().greaterThan(3));
button.disableProperty().bind(textFieldEntered.not());

Serialisierung von Properties

public class MyBean implements Serializable {
	private transient StringProperty sample = new SimpleStringProperty();
	public String getSample() {
		return sample.get();	
	}
	
	public void setSample(String value) {
		sample.set(value);
	}
	
	public StringProperty sampleProperty() {
		return sample;
	}
}
public class xyz implements Externalizable {
    private SimpleStringProperty x = new SimpleStringProperty("");
 
@Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        setX ((String) in.readObject());
    }
 
    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(getX());
    }

public class Packet implements Externalizable {
    private static final long serialVersionUID = -8256294089416034037L;
    private SimpleStringProperty varName = new SimpleStringProperty("");
    private SimpleStringProperty varValue = new SimpleStringProperty("");
 
    public Packet() {
        this("", "");
    }
    public Packet(String varName, String varValue) {
        setVarName(varName);
        setVarValue(varValue);
    }
    public String getVarName() {
        return varName.get();
    }
    public void setVarName(String var) {
        varName.set(var);
    }
   
    public String getVarValue() {
        return varValue.get();
    }
    public void setVarValue(String value) {
        varValue.set(value);
    }
    public SimpleStringProperty getVarNameProperty() {
        return varName;
    }
    public SimpleStringProperty getVarValueProperty() {
        return varValue;
    }
 
    @Override
    public String toString() {
        return getVarName() + ": " + getVarValue();
    }
 
    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        setVarName((String) in.readObject());
        setVarValue((String) in.readObject());
}
 
    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(getVarName());
        out.writeObject(getVarValue());
    }

ListView

// Definiere ListProperty -> es sollen Strings gespeichert werden
ListProperty<String> listProperty = new SimpleListProperty<>();

// Erstelle Collection mit Inhalt
List<String> iosList = new ArrayList<>();

iosList.add("iPhone 4");
iosList.add("iPhone 5");
iosList.add("iPhone 6");
iosList.add("iPhone SE");
iosList.add("iPhone 8");

// setzen der Werte durch umwandeln einer ArrayList in eine observableList
listProperty.set(FXCollections.observableArrayList(iosList));

// binde die ListView Items an die ListProperty
myListView.itemsProperty().bind(listProperty);

// ändere Elemente in der listProperty
listProperty.add("iPhone11");
listProperty.remove(0);

Task

task.setOnSucceeded((WorkerStateEvent event) -> {
   Object value = task.getValue();
   // do anything with the result
   updateTheUI(value);
});

// setOnFailed
// setOnScheduled
// setOnCanceled
// setOnRunning

Service

public CounterTask extends Task<Integer>{
   public CounterTask(int max) {
     this.max = max;
     updateMessage("Ready to count...");
   }
   @Override protected Integer call() throws Exception {
     updateMessage("Counting...");
     for (int i = 0; i < max; i++) {
       Thread.sleep(10);
       updateProgress(i, max);
     }
     updateMessage("READY");
     return max;
   }
}
public class CounterService extends Service<Integer>{
   private final int max;
   public CounterService(int max) {
     this.max = max;
   }
   @Override
   protected Task<Integer> createTask() {
     return new CounterTask(max);
   }
}

ScheduledService

public class CounterService extends ScheduledService<Integer>{
   private final int max;
   public CounterService(int max) {
	 super();
	 setPeriod(Duration.seconds(2));
     this.max = max;
   }
   @Override
   protected Task<Integer> createTask() {
     return new CounterTask(max);
   }
}
Label label = new Label();
label.textProperty().bind(Bindings.concat("Value: ",
    counterService.valueProperty()));
label.textProperty().bind(Bindings.concat("Value: ",
counterService.lastValueProperty()));
counterService.setRestartOnFailure(false);
counterService.start();
counterService.setRestartOnFailure(true);
counterService.setMaximumFailureCount(3);
counterService.start();
counterService.setRestartOnFailure(true);
counterService.setMaximumFailureCount(3);
counterService.setBackoffStrategy(
	ScheduledService.EXPONENTIAL_BACKOFF_STRATEGY );
counterService.start();

Progress anzeigen (unwahrscheinlich zur Matura)

Task task = new Task<Void>() {
	@Override public Void call() {
		static final int max = 1000000;
		for (int i=1; i<=max; i++) {
		if (isCancelled()) {
			break;
		}
		updateProgress(i, max);
	}
	return null;
	}
};

ProgressBar bar = new ProgressBar();
bar.progressProperty().bind(task.progressProperty());
new Thread(task).start();

Platform.runLater (unwahrscheinlich zur Matura)