import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
* A Swing application that downloads file from an HTTP server.
* @author www.codejava.net
public class Update extends JFrame implements PropertyChangeListener, ActionListener {
private static final long serialVersionUID = 1L;
private JLabel labelFileName = new JLabel("File name: ");
private JTextField fieldFileName = new JTextField(20);
private JLabel labelFileSize = new JLabel("File size (bytes): ");
private JTextField fieldFileSize = new JTextField(20);
private JLabel labelProgress = new JLabel("Progress:");
private JProgressBar progressBar = new JProgressBar(0, 100);
private JButton updateButton = new JButton("Update");
public static String[] libs = {
"adnroid", "antlr", "autocomplete", "bluecove-glp", "bluecove", "dx", "ecj",
"gdx-backend-android", "gdx-backend-lwjgl-natives", "gdx-backend-lwjgl", "gdx-natives", "gdx",
"proguard", "rsta", "socketio", "weblaflite"
String workDir = this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile();
String saveDir = workDir+"temp";
super("Swing File Download from HTTP server");
System.setProperty("jsse.enableSNIExtension", "false");
//startDownload("gdx.jar");
setLayout(new GridBagLayout());
GridBagConstraints constraints = new GridBagConstraints();
constraints.anchor = GridBagConstraints.WEST;
constraints.insets = new Insets(5, 5, 5, 5);
fieldFileName.setEditable(false);
fieldFileSize.setEditable(false);
progressBar.setPreferredSize(new Dimension(200, 30));
progressBar.setStringPainted(true);
constraints.weightx = 0.0;
constraints.gridwidth = 2;
constraints.fill = GridBagConstraints.NONE;
constraints.anchor = GridBagConstraints.CENTER;
add(updateButton, constraints);
updateButton.addActionListener(this);
constraints.gridwidth = 1;
constraints.anchor = GridBagConstraints.WEST;
add(labelFileName, constraints);
add(fieldFileName, constraints);
add(labelFileSize, constraints);
add(fieldFileSize, constraints);
constraints.gridwidth = 1;
constraints.anchor = GridBagConstraints.WEST;
add(labelProgress, constraints);
constraints.weightx = 1.0;
constraints.fill = GridBagConstraints.HORIZONTAL;
add(progressBar, constraints);
setLocationRelativeTo(null); // center on screen
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
public void actionPerformed(ActionEvent e){
new File(saveDir).mkdir();
//for(String file: libs){
int serverFileLength = getContentLength("https://github.com/pyros2097/Scene3d/raw/master/libs/"+file);
long localFileLength = new File(workDir+"libs/"+file).length();
GdxStudio.log("serverFileLength:"+serverFileLength+" localFileLength:"+localFileLength);
if(serverFileLength == localFileLength)
AsyncDownloader as = new AsyncDownloader("https://github.com/pyros2097/Scene3d/raw/master/libs/", file);
as.addPropertyChangeListener(this);
JOptionPane.showMessageDialog(this, "Error executing upload task: " + ex.getMessage(), "Error",
JOptionPane.ERROR_MESSAGE);
new File(saveDir).deleteOnExit();
public String getNewVersion(){
HttpURLConnection httpConn = openConnection("https://github.com/pyros2097/GdxStudio/raw/master/README.md");
return GdxStudio.version;
BufferedReader br = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
httpConn.getInputStream().close();
} catch (IOException e) {
return line.substring(10);
public HttpURLConnection openConnection(String url){
return (HttpURLConnection) new URL(url).openConnection();
} catch (MalformedURLException e) {
} catch (IOException e) {
public boolean isOK(HttpURLConnection httpConn){
return (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK);
} catch (IOException e) {
public int getContentLength(String fileURL){
HttpURLConnection httpConn = openConnection(fileURL);
int length = getContentLength(httpConn);
public int getContentLength(HttpURLConnection httpConn){
length = httpConn.getContentLength();
private boolean checkNewVersion(){
String[] vals1 = GdxStudio.version.split("\\.");
String[] vals2 = getNewVersion().split("\\.");
while(i<vals1.length && i<vals2.length && vals1[i].equals(vals2[i])) {
if (i<vals1.length && i<vals2.length) {
int diff = Integer.valueOf(vals1[i]).compareTo(Integer.valueOf(vals2[i]));
if(Integer.signum(diff) != 1)
void setFileInfo(String name, int size) {
fieldFileName.setText(name);
fieldFileSize.setText(String.valueOf(size));
* Update the progress bar's state whenever the progress of download changes.
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals("progress")) {
int progress = (Integer) evt.getNewValue();
progressBar.setValue(progress);
* Execute file download in a background thread and update the progress.
* @author www.codejava.net
public class AsyncDownloader extends SwingWorker<Void, Void> {
private static final int BUFFER_SIZE = 4096;
private String downloadURL;
public AsyncDownloader(String downloadURL, String fileName) {
this.downloadURL = downloadURL+fileName;
saveFile = new File(saveDir+ File.separator + fileName);
byte[] buffer = new byte[BUFFER_SIZE];
int percentCompleted = 0;
* Executed in background thread
protected Void doInBackground() throws Exception {
conn = openConnection(downloadURL);
fileSize = getContentLength(conn);
setFileInfo(saveFile.getName(), getContentLength(conn));
InputStream inputStream = conn.getInputStream();
FileOutputStream outputStream = new FileOutputStream(saveFile.getPath());
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
totalBytesRead += bytesRead;
percentCompleted = (int) (totalBytesRead * 100 / fileSize);
setProgress(percentCompleted);
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, "Error downloading file: " + ex.getMessage(),
"Error", JOptionPane.ERROR_MESSAGE);
* Executed in Swing's event dispatching thread
Files.copy(saveFile.toPath(), // replace existing files with downloaded files
new File(workDir+"libs/"+saveFile.getName()).toPath(),
StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e1) {
JOptionPane.showMessageDialog(null, "File has been downloaded successfully!", "Message",
JOptionPane.INFORMATION_MESSAGE);