Thursday, February 14, 2008

Java Applet: File uploader

I am a newbie in applet programming and very bad at programming. A google programmer ;). Recently i was trying to make an applet which could upload file to a php server, i started to googling and found that there are a lot of this kind of applet and none of them are not free :(. So i wanted to write one of my own and failed immediately as i didn't know how to run an applet. Again googling and learned to write applets.
Then i started to google how to show the file system in an applet, againg googling and found a code which can show your file system in a good tree way. But it was a normal java application not an applet, but i found it was easy to add to an applet. This is the code how you can show your file system in an applet. Thanks goes to Kirill Grouchnikov.


import java.awt.BorderLayout;
import java.awt.Component;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException;

import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.border.EmptyBorder;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.filechooser.FileSystemView;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeNode;


/**
* @author Kirill Grouchnikov
*/
public class FileTreePanel extends JPanel implements TreeSelectionListener,InterfaceHttpResponse{
String serverAddress = "http://www.smdprogramming.com/shimul/fup3/";
//String serverAddress = "http://localhost/fup3/";
/**
* File system view.
*/
protected static FileSystemView fsv = FileSystemView.getFileSystemView();

/**
* Renderer for the file tree.
*
* @author Kirill Grouchnikov
*/
private static class FileTreeCellRenderer extends DefaultTreeCellRenderer {
/**
* Icon cache to speed the rendering.
*/
private Map iconCache = new HashMap();

/**
* Root name cache to speed the rendering.
*/
private Map rootNameCache = new HashMap();

/*
* (non-Javadoc)
*
* @see javax.swing.tree.DefaultTreeCellRenderer#getTreeCellRendererComponent(javax.swing.JTree,
* java.lang.Object, boolean, boolean, boolean, int, boolean)
*/
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean sel, boolean expanded, boolean leaf, int row,
boolean hasFocus) {
FileTreeNode ftn = (FileTreeNode) value;
File file = ftn.file;
String filename = "";
if (file != null) {
if (ftn.isFileSystemRoot) {
// long start = System.currentTimeMillis();
filename = this.rootNameCache.get(file);
if (filename == null) {
filename = fsv.getSystemDisplayName(file);
this.rootNameCache.put(file, filename);
}
// long end = System.currentTimeMillis();
// System.out.println(filename + ":" + (end - start));
} else {
filename = file.getName();
}
}
JLabel result = (JLabel) super.getTreeCellRendererComponent(tree,
filename, sel, expanded, leaf, row, hasFocus);
if (file != null) {
Icon icon = this.iconCache.get(filename);
if (icon == null) {
// System.out.println("Getting icon of " + filename);
icon = fsv.getSystemIcon(file);
this.iconCache.put(filename, icon);
}
result.setIcon(icon);
}
return result;
}
}

/**
* A node in the file tree.
*
* @author Kirill Grouchnikov
*/
private static class FileTreeNode implements TreeNode {
/**
* Node file.
*/
public File file;

/**
* Children of the node file.
*/
private File[] children;

/**
* Parent node.
*/
private TreeNode parent;

/**
* Indication whether this node corresponds to a file system root.
*/
private boolean isFileSystemRoot;

/**
* Creates a new file tree node.
*
* @param file
* Node file
* @param isFileSystemRoot
* Indicates whether the file is a file system root.
* @param parent
* Parent node.
*/
public FileTreeNode(File file, boolean isFileSystemRoot, TreeNode parent) {
this.file = file;
this.isFileSystemRoot = isFileSystemRoot;
this.parent = parent;
this.children = this.file.listFiles();
if (this.children == null)
this.children = new File[0];
}

/**
* Creates a new file tree node.
*
* @param children
* Children files.
*/
public FileTreeNode(File[] children) {
this.file = null;
this.parent = null;
this.children = children;
}

/*
* (non-Javadoc)
*
* @see javax.swing.tree.TreeNode#children()
*/
public Enumeration children() {
final int elementCount = this.children.length;
return new Enumeration() {
int count = 0;

/*
* (non-Javadoc)
*
* @see java.util.Enumeration#hasMoreElements()
*/
public boolean hasMoreElements() {
return this.count < elementCount;
}

/*
* (non-Javadoc)
*
* @see java.util.Enumeration#nextElement()
*/
public File nextElement() {
if (this.count < elementCount) {
return FileTreeNode.this.children[this.count++];
}
throw new NoSuchElementException("Vector Enumeration");
}
};

}

/*
* (non-Javadoc)
*
* @see javax.swing.tree.TreeNode#getAllowsChildren()
*/
public boolean getAllowsChildren() {
return true;
}

/*
* (non-Javadoc)
*
* @see javax.swing.tree.TreeNode#getChildAt(int)
*/
public TreeNode getChildAt(int childIndex) {
return new FileTreeNode(this.children[childIndex],
this.parent == null, this);
}

/*
* (non-Javadoc)
*
* @see javax.swing.tree.TreeNode#getChildCount()
*/
public int getChildCount() {
return this.children.length;
}

/*
* (non-Javadoc)
*
* @see javax.swing.tree.TreeNode#getIndex(javax.swing.tree.TreeNode)
*/
public int getIndex(TreeNode node) {
FileTreeNode ftn = (FileTreeNode) node;
for (int i = 0; i < this.children.length; i++) {
if (ftn.file.equals(this.children[i]))
return i;
}
return -1;
}

/*
* (non-Javadoc)
*
* @see javax.swing.tree.TreeNode#getParent()
*/
public TreeNode getParent() {
return this.parent;
}

/*
* (non-Javadoc)
*
* @see javax.swing.tree.TreeNode#isLeaf()
*/
public boolean isLeaf() {
return (this.getChildCount() == 0);
}
}

/**
* The file tree.
*/
private JTree tree;

/**
* Creates the file tree panel.
*/
public FileTreePanel() {
this.setLayout(new BorderLayout());


File[] roots = File.listRoots();
FileTreeNode rootTreeNode = new FileTreeNode(roots);
this.tree = new JTree(rootTreeNode);
this.tree.setCellRenderer(new FileTreeCellRenderer());
this.tree.setRootVisible(false);

final JScrollPane jsp = new JScrollPane(this.tree);
jsp.setBorder(new EmptyBorder(0, 0, 0, 0));
this.add(jsp, BorderLayout.CENTER);

tree.addTreeSelectionListener(this);


}

testapp ta;
/**
* Creates the file tree panel.
*/
public FileTreePanel(testapp ta) {
this.ta = ta;
this.setLayout(new BorderLayout());


File[] roots = File.listRoots();
FileTreeNode rootTreeNode = new FileTreeNode(roots);
this.tree = new JTree(rootTreeNode);
this.tree.setCellRenderer(new FileTreeCellRenderer());
this.tree.setRootVisible(false);

final JScrollPane jsp = new JScrollPane(this.tree);
jsp.setBorder(new EmptyBorder(0, 0, 0, 0));
this.add(jsp, BorderLayout.CENTER);

tree.addTreeSelectionListener(this);


}
File currentFile= null;
public void valueChanged(TreeSelectionEvent e) {
// TODO Auto-generated method stub
FileTreeNode node = (FileTreeNode)
tree.getLastSelectedPathComponent();
System.out.println("slecte asldf "+node.isLeaf());
if(node.isLeaf())
{
currentFile = node.file;
System.out.println("File name "+currentFile.getName());
}
else
currentFile = null;


}


// public static void main(String[] args) {
// SwingUtilities.invokeLater(new Runnable() {
// public void run() {
// JFrame frame = new JFrame("File tree");
// frame.setSize(500, 400);
// frame.setLocationRelativeTo(null);
// frame.add(new FileTreePanel());
// frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// frame.setVisible(true);
// }
// });
// }
}




Now to add it to my applet this was the code


import java.applet.Applet;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

import org.omg.CORBA.FREE_MEM;


public class testapp extends Applet{
JTextField field;
JButton jb;
FileTreePanel ftreePanel;
public void init() {
//Execute a job on the event-dispatching thread:
//creating this applet's GUI.

try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
createGUI();
}
});
} catch (Exception e) {
System.err.println("createGUI didn't successfully complete");
}

addItem(false, "initializing... ");
}

private void createGUI() {
ftreePanel = new FileTreePanel(this);
add(ftreePanel);

// File[] roots = File.listRoots();
// FileTreeNode rootTreeNode = new FileTreeNode(roots);
// this.tree = new JTree(rootTreeNode);
// this.tree.setCellRenderer(new FileTreeCellRenderer());
// this.tree.setRootVisible(false);
// add(tree);

//Create the text field and make it uneditable.
field = new JTextField();
field.setEditable(false);
field.setAutoscrolls(true);
jb= new JButton("Upload");
jb.addActionListener(new ActionListener(){

public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
uploadJob();
}

});
jb.setSize(50, 50);
//add(jb);
JPanel jp = new JPanel();
jp.add(jb);
add(jp);
//Set the layout manager so that the text field will be
//as wide as possible.
setLayout(new java.awt.GridLayout(1,0));

//Add the text field to the applet.
add(field);



//new FileTreePanel();
}

public void start() {
addItem(false, "starting... ");
}

public void stop() {
addItem(false, "stopping... ");
}

public void destroy() {
addItem(false, "preparing for unloading...");
cleanUp();
}

private void cleanUp() {
//Execute a job on the event-dispatching thread:
//taking the text field out of this applet.
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
remove(field);
}
});
} catch (Exception e) {
System.err.println("cleanUp didn't successfully complete");
}
field = null;
}

private void addItem(boolean alreadyInEDT, String newWord) {
if (alreadyInEDT) {
addItem(newWord);
} else {
final String word = newWord;
//Execute a job on the event-dispatching thread:
//invoking addItem(newWord).
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
addItem(word);
}
});
} catch (Exception e) {
System.err.println("addItem didn't successfully complete");
}
}
}

//Invoke this method ONLY from the event-dispatching thread.
private void addItem(String newWord) {
String t = field.getText();
System.out.println(newWord);
field.setText(t + newWord);
}

void uploadJob(){
addItem("Upload button clicked");
ftreePanel.uploadFile();
}

void showMessage(String message)
{

field.setText(message);
}

}



you will some code are missing in previous FileTreePanel which will be added later on. The next thing came to my mind is how to get the node which is clicked in the file tree. It was very easy,u have to just implement the addTreeSelectionListener. For uploading part i used the java code which was posted previously during android file upload time. This function was added with FileTreePanel.java

public void uploadFile()
{
if(currentFile!= null)
{
ta.showMessage("Uploading file"+currentFile.getAbsolutePath());
System.out.println("Current file"+currentFile.getAbsolutePath());
String fileName = null;
try {
FileInputStream fis = new FileInputStream(currentFile);
fileName = currentFile.getName();
HttpFileUploader htfu = new HttpFileUploader(serverAddress+"test2.php","pngData", "", null,this);
System.out.println("File Name "+serverAddress+"test2.php");
htfu.doStart(fis,fileName);
ta.showMessage("Please wait");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ta.showMessage("File not found exception");
}
//ta.showMessage("Done Uploading file u can check at "+serverAddress+"uploads/"+fileName);

}
else
ta.showMessage("Not a file");

}


Now after completing everything the applet was running smoothly through Eclipse ide. But when i tried to run in browser the applet was not showing the file tree. I was in a problem then , I found that to access client pc resources you need to sign your applet with lengthy process. This link came great great help to me.

How to sign an applet

So after signing the applet it started to show it's face in the browser. The whole process took me 3 long days,damn i'm the slowest learner. You can check it here I don't know how long it will be available here. Whatever i am a happy monkey now. :D. You can find uploaded files here

[edited later]
The quest was not over yet, i was using jdk6 with jre6, so my applet was not showing into my friends pc whose jre was jre5.0. So i had to chnage the settings in eclipse and then remake the jar and the whole process.

15 Comments:

  1. Anonymous said...
    Hi Shimul,

    That was a great example, but can you upload the missing code please, I am using 1.4 and have midified teh code accordingly , byt dont see teh select All and Deseclt All Buttons and I dont see the child files also, you have filtered the file types to restrict to .jpg how did you do that?

    I need to have all the files but dont dont see any.

    Thanks.
    Shimul said...
    you can use filefilter class of java to filter a specific file type files or you can do the filtering manually, i used manual filtering :0
    Mefire said...
    Hi Shimul,

    nice example . I learned a lot from it but i ran into some problem. for my applet to compile , I have to remove any testapp class reference from the FileTreePanel class.

    Plz, help me out.

    attilah57@yahoo.fr

    waiting impatiently for your answer....
    Shimul said...
    @Mefire

    Hi i tried to send mail to your account, but delivery fails, can u tell what exact problem r u facing
    Mefire said...
    my email address is :

    attilah57@yahoo.com

    i made a mistake.
    Mefire said...
    hey, Shimul i got the problem fixed .

    but i'm facing another one now :

    this is what I want to do :

    Whenever a folder is clicked, its content(files) should be displayed on the right JPanel. the files displayed should have a checkbox on top.

    i've already displayed the files in the JPanel but the checkboxes won't show.

    any idea how to solve it ?

    thx.
    Mefire said...
    i want to design it like Aurigma Image Uploader . (list files with checkbox and multiple files upload).

    Any help would be welcome.

    thx.
    Anonymous said...
    Hi there Shimul,

    Great job with the applet, but there's some missing parts - at least under 1.4 it doesnt compile as it cant find InterfaceHttpResponse - is there a link to download the entire code ?

    thanks!

    jkritikos@gmail.com
    Shimul said...
    i will try to find the code, but can't assure you
    Anonymous said...
    much appreciated mate!

    jkritikos@gmail.com
    Sreekanth said...
    Great job with the applet, but there's some missing parts -so that it cant find InterfaceHttpResponse - is there a link to download the entire code ?


    The help would be appreciated
    Shimul said...
    interface code


    package jup;


    public interface InterfaceHttpResponse {
    public void httpResponse(String response);

    }
    Sreekanth said...
    nice example ?.. where can i find the HttpFileUploader jar. any ones help would be appreciated ...

    thanks
    Anonymous said...
    You can also compare to a java upload applet that provides both FTP and HTTP support.
    Arjuna Subagyo said...

Post a Comment