Created
November 4, 2014 10:49
-
-
Save bugabinga/54ef3373623212b6b4ca to your computer and use it in GitHub Desktop.
How to show progress indicators for long running GUI operations?
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.lpt.progress; | |
import java.util.Random; | |
import java.util.concurrent.CountDownLatch; | |
import java.util.concurrent.Executors; | |
import java.util.stream.IntStream; | |
import java.util.stream.Stream; | |
import javafx.application.Application; | |
import javafx.application.Platform; | |
import javafx.beans.property.LongProperty; | |
import javafx.beans.property.SimpleLongProperty; | |
import javafx.concurrent.Task; | |
import javafx.scene.Group; | |
import javafx.scene.Scene; | |
import javafx.scene.control.ProgressIndicator; | |
import javafx.scene.effect.DropShadow; | |
import javafx.scene.paint.Color; | |
import javafx.scene.shape.Circle; | |
import javafx.stage.Stage; | |
/** | |
* Testet das Auslagern von langen GUI-Operationen in JavaFx-Threads. | |
* | |
* @author okr | |
* | |
*/ | |
public class GuiTaskExample extends Application | |
{ | |
private static final Random RANDOM = new Random(); | |
private final static int WIDTH = 100; | |
private final static int HEIGHT = 100; | |
@Override | |
public void start( final Stage primaryStage ) | |
{ | |
final Group root = new Group(); | |
final Group circleGroup = new Group(); | |
final ProgressIndicator indicator = new ProgressIndicator(); | |
root.getChildren().add( circleGroup ); | |
root.getChildren().add( indicator ); | |
final Scene scene = new Scene( root ); | |
final GuiTaskExample that = this; | |
final Task<Void> task = new Task<Void>() | |
{ | |
@Override | |
protected Void call() throws Exception | |
{ | |
try (final IntStream intStream = RANDOM.ints( 1, HEIGHT )) | |
{ | |
final long maxSize = HEIGHT * WIDTH; | |
final Stream<Circle> circles = intStream.mapToObj( that::createCircleThing ).limit( maxSize ); | |
//local variables must be final for lambdas | |
final LongProperty counter = new SimpleLongProperty( 1 ); | |
circles.forEach( circle -> | |
{ | |
updateProgress( counter.get(), maxSize ); | |
counter.set( counter.get() + 1 ); | |
final CountDownLatch latch = new CountDownLatch( 1 ); | |
Platform.runLater( ( ) -> | |
{ | |
circleGroup.getChildren().add( circle ); | |
latch.countDown(); | |
} ); | |
try | |
{ | |
latch.await(); | |
} | |
catch ( final Exception e ) | |
{ | |
e.printStackTrace(); | |
} | |
} ); | |
final CountDownLatch latch = new CountDownLatch( 1 ); | |
Platform.runLater( ( ) -> | |
{ | |
primaryStage.sizeToScene(); | |
root.getChildren().remove( indicator ); | |
latch.countDown(); | |
} ); | |
latch.await(); | |
return null; | |
} | |
} | |
}; | |
indicator.progressProperty().bind( task.progressProperty() ); | |
task.exceptionProperty().addListener( ( observable, oldValue, newValue ) -> newValue.printStackTrace() ); | |
Executors.newSingleThreadExecutor().execute( task ); | |
primaryStage.setScene( scene ); | |
primaryStage.show(); | |
} | |
private Circle createCircleThing( final int radius ) | |
{ | |
final Circle circle = new Circle(); | |
circle.setRadius( RANDOM.nextInt( radius ) ); | |
circle.setCenterX( circle.getRadius() + RANDOM.nextInt( WIDTH ) ); | |
circle.setCenterY( circle.getRadius() + RANDOM.nextInt( HEIGHT ) ); | |
circle.setStrokeWidth( RANDOM.nextDouble() * 4 ); | |
circle.setStroke( randomPaint() ); | |
circle.setFill( randomPaint() ); | |
circle.setEffect( new DropShadow( RANDOM.nextInt( 12 ), randomPaint() ) ); | |
return circle; | |
} | |
private Color randomPaint() | |
{ | |
return Color.rgb( RANDOM.nextInt( 255 ), RANDOM.nextInt( 255 ), RANDOM.nextInt( 255 ), | |
RANDOM.nextDouble() ); | |
} | |
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