Java Zone FTPClient

Esta vez desarrollamos un cliente FTP, esta es su segunda entrega, la primera solo tenia funcionalidad pero no interfaz grafica. Seguiremos agregandole opciones.

Codigo

Clase Principal

package clases;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import javax.swing.*;

import org.apache.commons.net.ftp.FTPClient;

public class Principal extends JFrame{
 
 JTextArea consola;
 JSplitPane split;
 JPanel panelGUI,panelBotones;
 JScrollPane panelConsola;
 ArbolDirectorios arbolLocal,arbolRemoto;
 JButton btnTransARemoto;
 FTPClient ftp;
 
 public Principal(){
 
  colocarSkin();
 
  new FormularioAcceso(this);
 
  setLayout(new BorderLayout());
  consola=new JTextArea();
 
  split=new JSplitPane();
  split.setResizeWeight(0.5);
  arbolLocal=new ArbolDirectorios(this,1);
  arbolRemoto=new ArbolDirectorios(this,2);
  split.setLeftComponent(new JScrollPane(arbolLocal));
  split.setRightComponent(new JScrollPane(arbolRemoto));
 
  panelConsola=new JScrollPane(consola);
  panelConsola.setPreferredSize(new Dimension(300,140));
 
  panelBotones=new JPanel();
 
  btnTransARemoto=new JButton("Transferir");
  btnTransARemoto.addActionListener(new ActionListener(){

   @Override
   public void actionPerformed(ActionEvent arg0) {
    try {
     FileInputStream fis=new FileInputStream(arbolLocal.ruta);
     if(ftp.storeFile(arbolLocal.nombreArchivo,fis)){
      consola.append("Archivo Transferido \n");
            arbolRemoto.Raiz.removeAllChildren();
            arbolRemoto.modelo.reload();
            arbolRemoto.listaDirectorios(arbolRemoto.Raiz);
        }else
         consola.append("Error al Transferir el Archivo \n");
           
        fis.close();
    } catch (FileNotFoundException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
   
  });
 
  panelBotones.add(btnTransARemoto);
 
  panelGUI=new JPanel();
  panelGUI.setLayout(new BorderLayout());
  panelGUI.add(split,BorderLayout.CENTER);
  panelGUI.add(panelBotones,BorderLayout.SOUTH);
 
  add(panelGUI,BorderLayout.CENTER);
  add(panelConsola,BorderLayout.SOUTH);
 
  desactivarTodo();
 
 }
 
 public void desactivarTodo(){
  arbolLocal.explorador.setEnabled(false);
  arbolRemoto.explorador.setEnabled(false);
  consola.setEnabled(false);
 }
 
 public void activarTodo(){
  arbolLocal.explorador.setEnabled(true);
  arbolRemoto.explorador.setEnabled(true);
  consola.setEnabled(true);
 }
 
 private void colocarSkin() {
  try {
   UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
   } catch (ClassNotFoundException e) {
    e.printStackTrace();
   } catch (InstantiationException e) {
    e.printStackTrace();
   } catch (IllegalAccessException e) {
    e.printStackTrace();
   } catch (UnsupportedLookAndFeelException e) {
    e.printStackTrace();
   }
 }

 public static void main(String [] args){
  Principal p=new Principal();
  p.setVisible(true);
  p.setBounds(0, 0, 700, 400);
  p.setLocationRelativeTo(null);
  p.setDefaultCloseOperation(EXIT_ON_CLOSE);
 }

}

Clase FormularioAcceso

package clases;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;

import javax.swing.*;

import org.apache.commons.net.ftp.FTPClient;

public class FormularioAcceso extends JDialog{
 
 JPanel plogin;
 JTextField txtip,txtusuario;
 JPasswordField txtclave;
 JPanel panelBoton;
 JButton btnaceptar;
 Principal p;
 
 public FormularioAcceso(Principal prin){
 
  p=prin;
 
  plogin=new JPanel();
  plogin.setLayout(new GridLayout(3,2));
 
  txtip=new JTextField(10);
  txtusuario=new JTextField(10);
  txtclave=new JPasswordField(10);
 
  plogin.add(new JLabel("IP Servidor:"));
  plogin.add(txtip);
  plogin.add(new JLabel("Usuario:"));
  plogin.add(txtusuario);
  plogin.add(new JLabel("Contraseña:"));
  plogin.add(txtclave);
 
  JPanel paux=new JPanel();
  paux.add(plogin);
 
  panelBoton=new JPanel();
  btnaceptar=new JButton("Conectar");
  btnaceptar.addActionListener(new ActionListener(){

   @Override
   public void actionPerformed(ActionEvent arg0) {
     try {
     p.ftp = new FTPClient();
        p.ftp.connect(txtip.getText());
     if(p.ftp.login(txtusuario.getText(), new String(txtclave.getPassword()))){
         FormularioAcceso.this.dispose();
         p.activarTodo();
         p.arbolRemoto.swroot=true;
         p.arbolRemoto.listaDirectorios();
         p.arbolRemoto.updateUI();
         p.repaint();
         p.consola.append("Conectado al servidor "+txtip.getText()+" \n");
     }else{
         JOptionPane.showMessageDialog(null, "IP, usuario o Contraseña invalia.");
      p.desactivarTodo();
     }
    } catch (IOException e) {
     p.desactivarTodo();
     JOptionPane.showMessageDialog(null, "IP, usuario o Contraseña invalia.");
    }
   }
   
  });
  panelBoton.add(btnaceptar);
 
  add(paux);
  add(panelBoton,BorderLayout.SOUTH);
 
  this.setBounds(0, 0, 300, 140);
  this.setLocationRelativeTo(null);
  this.setAlwaysOnTop(true);
  this.setUndecorated(true);
  setVisible(true);
 
 }
}

Clase ArbolDirectorios

package clases;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.io.File;
import java.io.IOException;

import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;

import org.apache.commons.net.ftp.FTPFile;

public class ArbolDirectorios extends JPanel{
 
 JTree explorador;
 DefaultTreeModel modelo;
 DefaultMutableTreeNode Raiz,ultimoseleccionado;
 Principal p;
 int tipo=-1;
 boolean swroot=false;
 String ruta="";
 String nombreArchivo="";
 
 public ArbolDirectorios(Principal prin, int op){
 
  setLayout(new BorderLayout());
 
  p=prin;
  tipo=op;
 
  if(tipo==1){
   
      Raiz=new DefaultMutableTreeNode("Raiz");
      explorador=new JTree(Raiz);
      DefaultTreeCellRenderer render=(DefaultTreeCellRenderer)explorador.getCellRenderer();
      render.setLeafIcon(new ImageIcon(this.getClass().getResource("/lib/archivo.png")));
      render.setOpenIcon(new ImageIcon(this.getClass().getResource("/lib/carpeta.png")));
      render.setClosedIcon(new ImageIcon(this.getClass().getResource("/lib/carpeta.png")));
      explorador.addTreeSelectionListener(new TreeSelectionListener(){
 
   @Override
   public void valueChanged(TreeSelectionEvent arg0) {
    try{
     DefaultMutableTreeNode sel=(DefaultMutableTreeNode)explorador.getLastSelectedPathComponent();
     File fhijo=obtenerRuta(sel);
     ruta=fhijo.toString();
     nombreArchivo=sel.getUserObject().toString();
     if(swroot==false){
         
         for(int i=0;i<sel.getChildCount();i++){
          DefaultMutableTreeNode nieto=(DefaultMutableTreeNode)sel.getChildAt(i);
          agregarHijos(nieto);
         }
         swroot=true;
     }else{
      for(int i=0;i<sel.getChildCount();i++){
           DefaultMutableTreeNode nieto=(DefaultMutableTreeNode)sel.getChildAt(i);
           agregarHijos(nieto);
       }
     }
        }catch(NullPointerException npe){
         npe.printStackTrace();
        }
   }
     
     });
     
     for(int i=0;i<File.listRoots().length;i++){
       DefaultMutableTreeNode hijo=new DefaultMutableTreeNode(File.listRoots()[i]);
       Raiz.add(hijo);
     }  
     
  }else {
   Raiz=new DefaultMutableTreeNode("Raiz");
   modelo=new DefaultTreeModel(Raiz);
      explorador=new JTree(modelo);
      DefaultTreeCellRenderer render=(DefaultTreeCellRenderer)explorador.getCellRenderer();
      render.setLeafIcon(new ImageIcon(this.getClass().getResource("/lib/archivo.png")));
      render.setOpenIcon(new ImageIcon(this.getClass().getResource("/lib/carpeta.png")));
      render.setClosedIcon(new ImageIcon(this.getClass().getResource("/lib/carpeta.png")));
      explorador.addTreeSelectionListener(new TreeSelectionListener(){
 
   @Override
   public void valueChanged(TreeSelectionEvent arg0) {
    try{
     DefaultMutableTreeNode seleccionado=(DefaultMutableTreeNode)explorador.getLastSelectedPathComponent();
     DefaultMutableTreeNode se=null;
     if(seleccionado!=null){
      ruta=p.ftp.printWorkingDirectory()+"\\"+seleccionado.getUserObject();
     if(!seleccionado.isLeaf()){
      se=new DefaultMutableTreeNode(seleccionado.getUserObject());
      ultimoseleccionado=se;
      if(!se.toString().equalsIgnoreCase("Raiz")){
       Raiz.setUserObject(se.getUserObject());
       Raiz.removeAllChildren();
       modelo.reload();
       listaDirectorios(Raiz);
      }
     }
     }
        }catch(NullPointerException npe){
         npe.printStackTrace();
        } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
     }
   }
     
     });
  }
   
    add(explorador);
 }
 
  public void listaDirectorios(DefaultMutableTreeNode padre){
   
      FTPFile[] ftpFiles;
   try {
    p.ftp.changeWorkingDirectory(padre.toString());
    ftpFiles = p.ftp.listDirectories();
    for (FTPFile ftpFile : ftpFiles) {
     if (ftpFile.getType() == FTPFile.DIRECTORY_TYPE) {
          DefaultMutableTreeNode d=new DefaultMutableTreeNode(ftpFile.getName());
          DefaultMutableTreeNode d2=new DefaultMutableTreeNode("De clic en la carpeta");
          d.add(d2);
          padre.add(d);
     }
        }
    ftpFiles = p.ftp.listFiles();
    for (FTPFile ftpFile : ftpFiles) {
     if (ftpFile.getType() == FTPFile.FILE_TYPE) {
          DefaultMutableTreeNode d=new DefaultMutableTreeNode(ftpFile.getName());
          padre.add(d);
     }
        }
   } catch (IOException e) {
    e.printStackTrace();
   }
   explorador.expandRow(0);
   ArbolDirectorios.this.updateUI();
   p.repaint();
  }
 
  public void listaDirectorios(){
   
      FTPFile[] ftpFiles;
   try {
    ftpFiles = p.ftp.listDirectories();
    for (FTPFile ftpFile : ftpFiles) {
          if (ftpFile.getType() == FTPFile.DIRECTORY_TYPE) {
           DefaultMutableTreeNode d=new DefaultMutableTreeNode(ftpFile.getName());
           DefaultMutableTreeNode d2=new DefaultMutableTreeNode("De clic en la carpeta");
           d.add(d2);
           Raiz.add(d);
          }
        }
    ftpFiles = p.ftp.listFiles();
    for (FTPFile ftpFile : ftpFiles) {
     if (ftpFile.getType() == FTPFile.FILE_TYPE) {
          DefaultMutableTreeNode d=new DefaultMutableTreeNode(ftpFile.getName());
          Raiz.add(d);
     }
        }
   } catch (IOException e) {
    e.printStackTrace();
   }
   explorador.expandRow(0);
   ArbolDirectorios.this.updateUI();
   p.repaint();
  }
 
  public void agregarHijos(DefaultMutableTreeNode padre){
    if(padre!=Raiz){
     try{
       File fpadre=obtenerRuta(padre);
       if(fpadre.isDirectory()){
        if(fpadre.listFiles().length>0){
         for(int i=0;i<fpadre.list().length;i++){
          DefaultMutableTreeNode hijo=new DefaultMutableTreeNode(fpadre.list()[i]);
          padre.add(hijo);
         }  
        }
       }
     }catch(NullPointerException npe){
       
       }
    }
 }
 
 public File obtenerRuta(DefaultMutableTreeNode p){
    String ruta="";
    for(int i=0;i<p.getPath().length-1;i++){
     ruta=ruta+p.getPath()[i+1]+"\\";
    }
    File f=new File(ruta);
    return f;
 }
}

Descarga

Pueden descargar el archivo desde aquí, o pueden visitarnos en Java Zone para mas información sobre este proyecto.

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de Sr. Negativo

Muy buenas aplicaciones

Son muy útiles tus aplicaciones. Gracias por compartir.

Java Zone como siempre con

Java Zone como siempre con aplicaciones muy interesantes.

Estaría bien que usaras github para compartir tu código y/o que le pusieras alguna licencia open source.

Gracias

OscarRyz gracias por tus palabras, la verdad poco he usado este tipo de paginas para publicar el codigo, estoy en eso, viendo como funciona XD.

Imagen de neko069

Fuentes completos

A simple vista, los fuentes que acompañan el post crean la aplicación completa, porqué no los copias y verificas?

Excelente aplicacion

Seria de mejor opcion arrastrar los archivos y copiarlos del lado del servidor.