Created
July 9, 2016 06:51
-
-
Save russ-p/63d24c18fb9a702274df4e256d57c072 to your computer and use it in GitHub Desktop.
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 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