Coding

Open Source Drag & Drop Upload Java Applet for Websites

Screenshot Java Upload WidgetWith traditional HTML 4, file upload through a website is a cumbersome process, especially if you want to upload a large number of files. The recent surge of AJAX technologies has made web pages behave more like normal desktop applications, but it hasn’t been able to overcome the limitations of HTML4 since the ability of JavaScript to access the filesystem remains limited to using the INPUT tag in some form.

The most intuitive form of moving files from one location to another is to drag & drop them from a file sytem explorer window to the desired target.This is not possible on a webpage using JavaScript since JS cannot intercept such drops. Instead, the browser will open the dropped file.The only way to accomplish both intercepting a drop and to upload the dropped file to a remote server is to use an Flash or Java Applet.Since I know nothing of Flash, but a bit of Java, I did a search for Java Applets which could accomplish the task – thinking that there must be tons of such applets. Surprisingly, I didn’t find any that were both open source and ready-to-use.

Instead, there were many closed-sourced applets with restrictive and expensive licenses, and a few sites which offered code snippets. So I decided to try my luck and build on the code I found.

In particular, I used code from a tutorial by Zack Grossbart.

The result has the following features:

  • For each file to upload, a multipart/form-data POST request compatible to normal file upload forms is sent
  • Basic HTTP authentication
  • A progress bar that shows the progress of each individual file upload
  • A button to clear the upload list or cancel ongoing uploads
  • The code comes with a PHP script for the server that accepts the incoming data, but the backend could be written in any language.
  • Communication between Java and Javascript (LiveConnect) in order to
    • set a prefix to the filenames from JavaScript;
    • set the username and password for authentication from JavaScript;
    • call JavaScript functions when the user drops a non-file object on the drop area.
    • call JavaScript functions before, during and after the upload to allow JavaScript applications to update the UI.

If you want the code, there’s SVN acccess, and you can also download a GNU tarball. The code can be browsed online here. If you have suggestions how to improve the code, leave a note or send a diff to info/at/bibliograph/dot/org.

P.S.There are some wierd issues:

  • One problem exists with LiveConnect (the ability of the applet to access JavaScript objects and methods) when the applet is embedded in an <iframe>: When a function called by the applet is accessing the parent frame, and the code in the parent frame is doing i/o stuff, LiveConnect stops working, i.e. the functions in the iframe are not called any longer. No error is thrown (I tested it in Firefox 2.0.0.12 and Safari 3.04). I got it to work by putting the i/o stuff (a httpxml-request) into a 500ms timeout. Also, the parent frame functions should make a copy of objects passed by the applet (i.e., myArray = arraySentByApplet.join(“–separator–“).split(“–separator–“)) before sending them to other functions, since there seem to be issues with them, too.
  • The other concerns the visibility of the applet. When the iframe is hidden (for example, when it is part of a tab page that is not active), and then become visible again, it is not repainted. A call to “repaint” doesn’t help, and I couldn’t figure out how to deal with th “paint(Graphics g)” method. I ended up with a programmatic resizing of the iframe – then the applet is redrawn. This occurred in Firefox, but not in Safari.
  • Finally, when there are more than one Firefox instance displaying the same applet, drag and drop doesn’t work anymore and a NullPointerException is thrown. A similar problem is described here.

Update:

  • I have not tested the previous points for later browser versions, please let us know if they still exist.
  • An alternative java applet can be found here.
  • If you don’t like java applets, try Digitarald’s “Fancy Upload” based on Flash.
  • Multiple-File upload is coming in HTML5 and some browsers already support it. The java applet will might no longer be required.

44 thoughts on “Open Source Drag & Drop Upload Java Applet for Websites

  1. I grabbed the code to see if I could further customize it and one thing I am noticing is that it full on crashes Firefox 3 Beta 5. This is not necessarily an indicator of problems with the applet as merely visiting msn.com also crashes this version of Firefox.

  2. Hi, would it be possible to get some detailed information about how to e.g. pass more optional form text-fields from the frontend to backend and how to read it out in the backand to work with it?

    very nice project, go on that way. but please give the interessed more details about the usage. I got it to run and used my php-knowlidge to validate extensions of files to be uploaded. isn´t there a better way throug the appled direkt?

    thnx. for your nice work and I´ll stay tuned…

    AceLine

  3. I noticed the same problem as Chris, so it’s proboably just an issue with Firefox 😦 Time to re-install Firefox 2.

  4. AceLine,

    sorry for not responding in a while – at the moment, I cannot work on this unfortunately, and you’ll have to look at the java source for more information. As it is now, the only information that you can pass together with the uploaded file is th “metadata” field, so you can serialize all kind of information into a string and pass it as “metadata” for PHP to parse into separate pieces of information. It actually would be trivial to add more fields, but you’ll have to hack the java source to do that… I am a PHP hobbyist, but I found it quite accessible once I had Eclipse up and running, so why don’t you give it a try? 😉

    Sorry for not being able to be more of help!

    Christian

  5. Sorry for the random question, but I’m trying to get a drag and drop uploader, using some of the code you have here, to work but there’s a problem with the certificate. I’ve self-signed my jar (same as you, correct?) but when I load the webpage that it’s on it just loads the applet right away and doesn’t pop up the dialog box that asks if I want to trust the applet. I’m just signing the jar manually with jarsigner, not with ant, do you think that could be the problem? I’ve looked everywhere about this and all the sites just seem to say “when a browser loads a self-signed applet it will ask the user whether or not to accept the certificate.”

    Any help would be much appreciated, and I already am very thankful for the code you (and Zack Grossbart) have made open source. Thanks!

  6. Austin:

    I am afraid I don’t know enough about signing jars. As you know, most code is copied from Zack, I have only modified it to suit my needs. Maybe we have a reader with more knowledge on this?

    Sorry that I can’t be more helpful,

    Christian

  7. Hi Panyasan,

    The script and example look great!
    I’m afraid I’m facing a non-PHP related problem, just when the upload is finished. I get the following message in the upload window:
    “An error occurred: cannot retry due to server authentication, in
    streaming mode”.

    From what I read on a few websites, I should add some code to the header of the file (upload.php), which I did:
    header(‘HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy()’);
    header(‘httpClientPolicy.setAllowChunking(false)’);
    header(‘httpConduit.setClient(httpClientPolicy)’);

    Still facing the same problem.
    Any help is very welcome!

    Cheers,

    Marijn

    1. Did you ever figure this out? I get this problem also, but only once in a while (maybe 1 in 20 uploads).

      1. Hi Kenton, I have not done any work on the applet ever since I have published it. Sorry. I whish newer browser or java versions would make the bugs go away, but I guess that is whishful thinking.

  8. This is very interesting and promising. Do you know of somebody that has been able to translate this into C#?

  9. Thank you so much. This is what I need. I had created a backend
    drag drop document management page. This will add more functionality.

    I will back when I have time. Cheers!

  10. Is there any way to add input fields right after you drop a file in there? I need to be able to upload video files and if I could get some input fields in there so i can type the height and the width of the video to be uploaded that would be great.

  11. @Marjin: The header() command in PHP can only be used with http headers, not with java commands.

    @NachoLiberated: Why would you want to do this? Then it won’t work as an applet any more.

    @Jack: Great – please share your improvements with us!

    @Levi: You can use the “metadata” field to pass all kind of information to the backend. Use javascript to serialize additional field values and store it in the “metadata”. AFter upload, you just need to unserialize this field into the needed fields.

  12. Hello panyasan,

    I tried your applet and found it really nice.
    Just wanted to translate it into Italian, but I got into a kinda nasty problem.

    I managed somehow to compile and sign the applet (I suppose correctly, since I get the dialog asking whether to run it or not, and it does not give the “securityException” error anymore), but when I press the upload button it does nothing.

    I tried putting some debug output and I think that the code creating the thread that handles the upload is not running at all.

    I tried to compile your original code and my modified code, in eclipse they both run smoothly, in browser none of them work 😦

    That’s why I am quite confident that there is something wrong either with signing or compiling but I really can’t figure it out, could you please tell me how exactly did you compile and sign the JAR?

    Thanks!!
    Davide

  13. Hello Davide,

    I am using the Eclipse ANT file launcher which does everything for me. The ANT file was included in the package provided by Zack Grossbart and I have only slightly modified it. As I said, I am a Java amateur – everything has been done using a “trial & error” approach. So I am afraid I cannot give you any more detailed explanations…

    Christian

  14. Is it just me or does anything over 3700kb makes the application hang and freeze up? Tried it in Chrome and IE7 with same effect, is there a compiled updated version?? I’ve kinda got rusty coding in Java – I saw the dark side and went over to dotNet. The app is great though (thanks).

    Doing it in c# is surprisingly easy.
    @NachoLiberated: It’s pretty simple to translate into c#, see below. The problem is however, i can’t seem to pull the metadata field out of the stream.

    I guess because it’s a seralizable field which i have no knowledge of.. plus it may be a restriction of a java web server (i’m currently using Abyss Web server with .Net 3.5)
    c# Drag and drop Example
    if (Request.Files.Count> 0)
    {
    //Response.Write(Request.Files[0].FileName+”\n”);
    //Response.Write(Request.Files[0].ContentLength + “\n”);
    Request.Files[0].SaveAs(“c:\\” + Request.Files[0].FileName);
    Response.Write(“Saved!” + “\n”);
    }
    It sends the files recursively so you’ll need to loop this command until you hit an exception.

    regards
    Dan

  15. Hi. Nice project, but there is still big problem with large files… but you could send only “packages” of (let’s say) 500KB and put them together on server side (the backend)… what do you think?

  16. The “Cancel” feature doesn’t seem to work quite right. I tried it out by using a large file (11MB), and when I hit the cancel it stopped, but not naturally. Instead of displaying the message it’s supposed to in red, everything just came to a halt and appeared frozen.

    But otherwise this is a great script; thank you.

  17. @Gordon: Yes, this doesn’t work. Uploads can only be cancelled between each upload, because I didn’t know how to properly abort an ongoing stream connection.

    @Hawwwran: You’re welcome to implement this 😉

  18. Is there a way to stop or halt or maybe destroy the applet after a user goes to a different page. Example….I drop a file from my desktop onto the applet. After it uploads i go to a different page. Then I want to delete the file off of my desktop but it will not delete because it says its being used by another program. When I close the browser, then I can delete the file. I really need this to happen. Any thoughts?

    Levi

  19. This is a nice Applet. Thank you for bringing it to public.

    BTW, I wonder if it is possible to make this Applet invisible. For instance, the size of this Applet will become 1×1. The user will simply drag and drop files to a web-page which contain this Applet. In other words, the entire web-page will be a target for drag-n-drop but not be restricted by the size of Applet.

    Thank you,
    Jongbeom

  20. can someone post a working link for this very nice open source code??

    i would like to use it but the link above does not work.

    Sjaak

  21. This is GREAT news. I´ve been waiting for something like this for years.

    I do not agree that HTML5 and Ajax will make this obsolete. There´s a strong need for something Java based that works on any OS and browser, and interfaces with legacy systems that use html forms and one-by-one file uploads.

    I have used plenty of CMS systems with legacy html form file uploads.

    Seriously, Oracle/Sun should hire you (or put it another way, if I worked at Sun/Oracle, I´d hire you!) to work on this full time and make it the best multiple file upload solution, perhaps porting it to a JavaFX based solution using JDIC and allowing one to dock the drop area to the windows systray and gnome panel.

    But now to the most important stuff:

    1. I clicked on the link to download the .tar.gz and got a broken link message. Where to download the source, now?
    2. Do I have your permission to create a project page at SourceForge.net? that way others can continue evolving this project.
    3. What is the license?. GPL v2 would be nice.

    Best Regards

    FC
    Buenos Aires, Argentina

    1. Hello Fernando,

      concerning your questions:

      1) I have updated the .tar link – Can you try again? Otherwise, go to the new ViewVC link next to it – on this page, there is a “Download Tarball” link.

      2) You are more than welcome to take the code and create a new sourceforge project from it. I no longer maintain it anyways, and much of the code is not authored by me, but by Zack Grossbart. This is the spirit of Open Source – take code and develop it further!

      3) Please have a look at the code – I don’t actually remember how it was originally licensed by Zack. GPL v2 is fine with me, too.

      Thanks,
      Christian

  22. Hi.
    I tested you code with asp.NET and it worked very well, since there was one more that had problems reading the files i will post the code here.

    a couple of things though

    1) i have modified the applet so as just send one file

    2) i have modified the tail (so as to not care about the end boundary (if i removed the tail completely i got corrupted transfers)
    applet code now : String tail = “\r\n”;

    3) the .NET code isn’t cleaned up yet so please don’t be mad at me 🙂 i have set the page to have write rights in IIS to folder
    C:\Inetpub\wwwroot\FileUploadTestNET\UserData\

    ok here goes :
    just create a new webpage and put this in the .cs code

    protected void Page_Load(object sender, EventArgs e)
    {

          StreamReader sr = new StreamReader(Request.InputStream, Encoding.Default);

          if (sr.BaseStream.Length > 100) //empty input
          {
            //METADATA
            String tmp1 = sr.ReadLine();
            String tmp2 = sr.ReadLine();
            String tmp3 = sr.ReadLine();
            String tmp4 = sr.ReadLine();
            String tmp5 = sr.ReadLine();

            String filenameMeta = sr.ReadLine(); //contains filename
            String tmp7 = sr.ReadLine();
            String tmp8 = sr.ReadLine();
            String tmp9 = sr.ReadLine();
            String tmp10 = sr.ReadLine();

            String removeFront = filenameMeta.Substring(filenameMeta.IndexOf("filename=\"") + ("filename=\"").Length);
            String filename = removeFront.Substring(0, removeFront.IndexOf('.') + 4);

            StreamWriter myWriter = new StreamWriter(@"C:\Inetpub\wwwroot\FileUploadTestNET\UserData\"+filename, false, Encoding.Default);

            while (!sr.EndOfStream)
            {
              myWriter.Write(sr.ReadToEnd());
            }

            myWriter.Close();
            sr.Close();
          }
          else
          {
            Response.Write("Empty input");
            sr.Close();
          }

          Response.Write("Finished");
    }
    }

    //cheers Kristoffer

  23. Hi panysan…

    Thanks a lot for you excellent code…

    I tested you code for my project (back end: Java Servlet)and it worked fine. However I will be enhancing your code in coming week for following
    1) load images(strictly)
    2) show thumbnails
    3) resize image to 3 different sizes(small, medium and large)
    4) upload all of them to server

    I will come back for help and suggestions

  24. Hi panyasan…
    I need one help here.

    I enhance your to show thumbnail of the dropped image file. Which works fine with applet viewer but when i try this applet in browser, I can’t see the image thumnails in drop zone..

    I tried debugging it and found that there is some issue with following line

    Image img= Imageio.read(f);

    I found that even while executing f.getAbsolutePath(), applet stops working (however,everything works fine in applet viewer )

  25. Wow. Thank you so much for this. I needed something that works with Internet Explorer, because as much as people would like to deny it, as of 2012 over 75% of the people out there still use IE.

    I am using your applet directly, without iframes, and there are no bugs can I can see. Got it working with C# backend in 5 minutes. Fantastic!

    1. Yes, sorry. But the code is really old now and – given the power of HTML5 – no longer needed…

      1. hi,
        i tried your code (not fully but upload part) and found when file size less than 4MB ,progress bar completed 100% quickly and but actual output takes time. is there nay particular reason.

      2. Hi. Really. Don’t use Java applets any more. They are a security hazard, and HTML5/Javascript can handle this much better…

        @everybody
        Thanks for your interest and your comments over the years! This has been my first and most popular post on this blog. I am now closing the comments for it, because I won’t be able to respond to any questions related to this applet. As I said, there is no need for a Java-based uploader any more.

Comments are closed.