Created
June 24, 2016 09:08
-
-
Save bugabinga/a375f3435a867290e1b8223ee89d1a4a to your computer and use it in GitHub Desktop.
Exploring Properties and Threads in JavaFx for StackOverflow Question https://stackoverflow.com/questions/38001595/javafx-only-update-binding-after-all-dependencies-are-updated
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
package com.isp.stackoverflow; | |
import java.math.BigDecimal; | |
import java.math.BigInteger; | |
import java.util.Random; | |
import java.util.concurrent.ExecutorService; | |
import java.util.concurrent.Executors; | |
import java.util.concurrent.ThreadLocalRandom; | |
import javafx.application.Application; | |
import javafx.application.Platform; | |
import javafx.beans.binding.Bindings; | |
import javafx.beans.binding.ObjectBinding; | |
import javafx.beans.property.Property; | |
import javafx.beans.property.SimpleObjectProperty; | |
import javafx.concurrent.Task; | |
import javafx.scene.Scene; | |
import javafx.scene.control.Label; | |
import javafx.scene.control.Separator; | |
import javafx.scene.layout.VBox; | |
import javafx.stage.Stage; | |
/** | |
* https://stackoverflow.com/questions/38001595/javafx-only-update-binding-after-all-dependencies-are-updated | |
* | |
* @author okr | |
* @date 24.06.2016 | |
* | |
*/ | |
public class PropertiesWithThreads extends Application | |
{ | |
private final ExecutorService executor = Executors.newFixedThreadPool( 2 ); | |
private final Property<BigDecimal> a = | |
new SimpleObjectProperty<>( newRandomBigDecimal( ThreadLocalRandom.current(), 10 ) ); | |
private final Property<BigDecimal> b = | |
new SimpleObjectProperty<>( newRandomBigDecimal( ThreadLocalRandom.current(), 10 ) ); | |
private final Task<Void> taskAB = new Task<Void>() | |
{ | |
@Override | |
protected Void call() throws Exception | |
{ | |
while ( !isCancelled() ) | |
{ | |
Thread.sleep( 2000 ); | |
System.out.println( "Updating A!" ); | |
Platform.runLater( () -> a | |
.setValue( newRandomBigDecimal( ThreadLocalRandom.current(), 10 ) ) ); | |
Thread.sleep( 2000 ); | |
System.out.println( "Updating B!" ); | |
Platform.runLater( () -> b | |
.setValue( newRandomBigDecimal( ThreadLocalRandom.current(), 10 ) ) ); | |
} | |
return null; | |
} | |
}; | |
private final ObjectBinding<BigDecimal> c = new ObjectBinding<BigDecimal>() | |
{ | |
{ | |
super.bind( a, b ); | |
} | |
@Override | |
protected BigDecimal computeValue() | |
{ | |
return a.getValue().add( b.getValue() ); | |
} | |
}; | |
private final ObjectBinding<BigDecimal> cOnlyOnBChange = new ObjectBinding<BigDecimal>() | |
{ | |
{ | |
super.bind( b ); | |
} | |
@Override | |
protected BigDecimal computeValue() | |
{ | |
return a.getValue().add( b.getValue() ); | |
} | |
}; | |
private final Task<Void> taskC = new Task<Void>() | |
{ | |
@Override | |
protected Void call() throws Exception | |
{ | |
cOnlyOnBChange.addListener( ( __, ___, newValue ) -> System.out | |
.println( "C changed to " + newValue ) ); | |
return null; | |
} | |
}; | |
BigDecimal getC() | |
{ | |
return c.getValue(); | |
} | |
private static BigDecimal newRandomBigDecimal( final Random random, final int precision ) | |
{ | |
final BigInteger n = BigInteger.TEN.pow( precision ); | |
return new BigDecimal( newRandomBigInteger( n, random ), precision ); | |
} | |
private static BigInteger newRandomBigInteger( final BigInteger n, final Random random ) | |
{ | |
BigInteger r; | |
do | |
{ | |
r = new BigInteger( n.bitLength(), random ); | |
} while ( r.compareTo( n ) >= 0 ); | |
return r; | |
} | |
@Override | |
public void start( final Stage primaryStage ) | |
{ | |
final Label labelA = new Label(); | |
final Label labelB = new Label(); | |
final Label labelC = new Label(); | |
labelA.textProperty().bind( Bindings.format( "A = %s", a ) ); | |
labelB.textProperty().bind( Bindings.format( "B = %s", b ) ); | |
labelC.textProperty().bind( Bindings.format( "C = %s", c ) ); | |
final VBox root = new VBox( 16, labelA, labelB, new Separator(), labelC ); | |
primaryStage.setScene( new Scene( root ) ); | |
primaryStage.show(); | |
executor.execute( taskAB ); | |
executor.execute( taskC ); | |
primaryStage.setOnCloseRequest( __ -> | |
{ | |
executor.shutdownNow(); | |
primaryStage.close(); | |
} ); | |
} | |
/** | |
* @param args ignore. | |
*/ | |
public static void main( final String[] args ) | |
{ | |
launch( args ); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment