Skip to content

Instantly share code, notes, and snippets.

@russ-p
Created July 9, 2016 06:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save russ-p/63d24c18fb9a702274df4e256d57c072 to your computer and use it in GitHub Desktop.
Save russ-p/63d24c18fb9a702274df4e256d57c072 to your computer and use it in GitHub Desktop.
package dl;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.atomic.AtomicLong;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
/**
*
* http://ru.stackoverflow.com/questions/542135/
*/
public class DLApp extends Application {
public static void main(String[] args) throws Exception {
launch(args);
}
private DownloadTask downloadTask;
public void start(Stage stage) throws Exception {
VBox rootNode = new VBox();
Label label = new Label();
Label stateLabel = new Label();
Label speedLabel = new Label();
ProgressIndicator progressIndicator = new ProgressIndicator();
Button button = new Button("Start");
button.setOnAction((e) -> {
downloadTask = new DownloadTask("http://speedtest.wdc01.softlayer.com/downloads/test10.zip",
"/tmp/test10.zip");
stateLabel.textProperty().bind(downloadTask.stateProperty().asString());
label.textProperty().bind(downloadTask.messageProperty());
speedLabel.textProperty().bind(downloadTask.speedProperty().asString("Speed: %.3f MB/s"));
progressIndicator.progressProperty().bind(downloadTask.progressProperty());
Thread th = new Thread(downloadTask);
th.setDaemon(true);
th.start();
});
Button stopButton = new Button("Stop");
stopButton.setOnAction((e) -> {
if (downloadTask != null && downloadTask.isRunning()) {
downloadTask.cancel();
}
});
rootNode.getChildren().add(label);
rootNode.getChildren().add(stateLabel);
rootNode.getChildren().add(speedLabel);
rootNode.getChildren().add(progressIndicator);
rootNode.getChildren().add(new HBox(4, button, stopButton));
Scene scene = new Scene(rootNode, 400, 200);
stage.setTitle("App");
stage.setScene(scene);
stage.show();
}
class DownloadTask extends Task<Void> {
private static final int BUFF_SIZE = 10000;
private String url;
private String savePath;
public DownloadTask(String url, String savePath) {
this.url = url;
this.savePath = savePath;
}
@Override
protected Void call() throws Exception {
URL connection = new URL(url);
HttpURLConnection urlconn;
long size;
urlconn = (HttpURLConnection) connection.openConnection();
urlconn.setRequestMethod("GET");
size = urlconn.getContentLengthLong();
updateMessage("Size: " + size);
urlconn.connect();
try (
/* Set input stream */
InputStream in = urlconn.getInputStream();
/* Set write stream */
OutputStream writer = new FileOutputStream(savePath);) {
byte buffer[] = new byte[BUFF_SIZE];
/* Download */
int i = 0;
long i_sum = 0;
long delta_t = System.nanoTime();
double getted_b = 0.0;
while ((i = in.read(buffer)) > 0) {
writer.write(buffer, 0, i);
getted_b += i;
i_sum += i;
updateProgress(i_sum, size);
if ((System.nanoTime() - delta_t) >= 1E9) {
Double speed = new BigDecimal(getted_b / Math.pow(10, 6)).setScale(3, BigDecimal.ROUND_HALF_UP)
.doubleValue();
updateSpeed(speed);
delta_t = System.nanoTime(); // Set to zero
getted_b = 0.0;
}
if (isCancelled()) {
return null;
}
}
/* Cleaning */
writer.flush();
}
return null;
}
private final DoubleProperty speed = new SimpleDoubleProperty();
public final DoubleProperty speedProperty() {
return this.speed;
}
public final double getSpeed() {
return this.speedProperty().get();
}
public final void setSpeed(final double speed) {
this.speedProperty().set(speed);
}
private AtomicLong speedUpdate = new AtomicLong();
//see javafx.concurrent.Task.updateProgress()
protected void updateSpeed(double speed) {
if (Platform.isFxApplicationThread()) {
setSpeed(speed);
} else if (speedUpdate.getAndSet(Double.doubleToLongBits(speed)) == 0L) {
Platform.runLater(() -> {
final double _speed = Double.longBitsToDouble(speedUpdate.getAndSet(0L));
setSpeed(_speed);
});
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment