/* * Site.java * * Created on Jan 2, 2011, 9:44:13 PM * * @author pquiring */ import java.awt.event.*; import java.io.*; import java.awt.*; import java.util.*; import java.text.*; import javax.swing.*; import javax.swing.tree.*; import javax.swing.table.*; import javaforce.*; public abstract class Site extends javax.swing.JPanel implements FTP.ProgressListener { /** * Creates new form Site */ public Site() { initComponents(); } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { localMenu = new javax.swing.JPopupMenu(); local_upload = new javax.swing.JMenuItem(); jSeparator1 = new javax.swing.JPopupMenu.Separator(); local_mkdir = new javax.swing.JMenuItem(); local_refresh = new javax.swing.JMenuItem(); jSeparator2 = new javax.swing.JPopupMenu.Separator(); local_delete = new javax.swing.JMenuItem(); local_rename = new javax.swing.JMenuItem(); remoteMenu = new javax.swing.JPopupMenu(); remote_download = new javax.swing.JMenuItem(); jSeparator4 = new javax.swing.JPopupMenu.Separator(); remote_mkdir = new javax.swing.JMenuItem(); remote_refresh = new javax.swing.JMenuItem(); jSeparator5 = new javax.swing.JPopupMenu.Separator(); remote_delete = new javax.swing.JMenuItem(); remote_rename = new javax.swing.JMenuItem(); jSeparator6 = new javax.swing.JPopupMenu.Separator(); remote_props = new javax.swing.JMenuItem(); split_main = new javax.swing.JSplitPane(); split_files = new javax.swing.JSplitPane(); localSide = new javax.swing.JPanel(); jLabel2 = new javax.swing.JLabel(); localDir = new javax.swing.JTextField(); split_local = new javax.swing.JSplitPane(); jScrollPane2 = new javax.swing.JScrollPane(); localTree = new javax.swing.JTree(); jScrollPane4 = new javax.swing.JScrollPane(); localFiles = new javax.swing.JTable(); remoteSide = new javax.swing.JPanel(); jLabel1 = new javax.swing.JLabel(); remoteDir = new javax.swing.JTextField(); split_remote = new javax.swing.JSplitPane(); jScrollPane1 = new javax.swing.JScrollPane(); remoteTree = new javax.swing.JTree(); jScrollPane3 = new javax.swing.JScrollPane(); remoteFiles = new javax.swing.JTable(); status_pane = new javax.swing.JTabbedPane(); jPanel1 = new javax.swing.JPanel(); progress = new javax.swing.JProgressBar(); status = new javax.swing.JLabel(); abort = new javax.swing.JButton(); jPanel2 = new javax.swing.JPanel(); jScrollPane5 = new javax.swing.JScrollPane(); log = new javax.swing.JTextArea(); local_upload.setText("Upload"); local_upload.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { local_uploadActionPerformed(evt); } }); localMenu.add(local_upload); localMenu.add(jSeparator1); local_mkdir.setText("Create Directory"); local_mkdir.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { local_mkdirActionPerformed(evt); } }); localMenu.add(local_mkdir); local_refresh.setText("Refresh"); local_refresh.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { local_refreshActionPerformed(evt); } }); localMenu.add(local_refresh); localMenu.add(jSeparator2); local_delete.setText("Delete"); local_delete.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { local_deleteActionPerformed(evt); } }); localMenu.add(local_delete); local_rename.setText("Rename"); local_rename.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { local_renameActionPerformed(evt); } }); localMenu.add(local_rename); remote_download.setText("Download"); remote_download.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { remote_downloadActionPerformed(evt); } }); remoteMenu.add(remote_download); remoteMenu.add(jSeparator4); remote_mkdir.setText("Create Directory"); remote_mkdir.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { remote_mkdirActionPerformed(evt); } }); remoteMenu.add(remote_mkdir); remote_refresh.setText("Refresh"); remote_refresh.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { remote_refreshActionPerformed(evt); } }); remoteMenu.add(remote_refresh); remoteMenu.add(jSeparator5); remote_delete.setText("Delete"); remote_delete.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { remote_deleteActionPerformed(evt); } }); remoteMenu.add(remote_delete); remote_rename.setText("Rename"); remote_rename.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { remote_renameActionPerformed(evt); } }); remoteMenu.add(remote_rename); remoteMenu.add(jSeparator6); remote_props.setText("Properties"); remote_props.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { remote_propsActionPerformed(evt); } }); remoteMenu.add(remote_props); addComponentListener(new java.awt.event.ComponentAdapter() { public void componentResized(java.awt.event.ComponentEvent evt) { formComponentResized(evt); } public void componentShown(java.awt.event.ComponentEvent evt) { formComponentShown(evt); } }); split_main.setDividerLocation(400); split_main.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); split_files.setDividerLocation(300); localSide.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED)); jLabel2.setText("Local site:"); localDir.setEditable(false); localDir.setText("/"); split_local.setDividerLocation(200); split_local.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); javax.swing.tree.DefaultMutableTreeNode treeNode1 = new javax.swing.tree.DefaultMutableTreeNode("root"); localTree.setModel(new javax.swing.tree.DefaultTreeModel(treeNode1)); localTree.setComponentPopupMenu(localMenu); localTree.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { localTreeMouseClicked(evt); } }); jScrollPane2.setViewportView(localTree); split_local.setTopComponent(jScrollPane2); jScrollPane4.setComponentPopupMenu(localMenu); localFiles.setModel(new javax.swing.table.DefaultTableModel( new Object [][] { {null, null, null, null}, {null, null, null, null}, {null, null, null, null}, {null, null, null, null} }, new String [] { "Title 1", "Title 2", "Title 3", "Title 4" } )); localFiles.setComponentPopupMenu(localMenu); localFiles.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { localFilesMouseClicked(evt); } }); localFiles.addKeyListener(new java.awt.event.KeyAdapter() { public void keyPressed(java.awt.event.KeyEvent evt) { localFilesKeyPressed(evt); } }); jScrollPane4.setViewportView(localFiles); split_local.setRightComponent(jScrollPane4); javax.swing.GroupLayout localSideLayout = new javax.swing.GroupLayout(localSide); localSide.setLayout(localSideLayout); localSideLayout.setHorizontalGroup( localSideLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(localSideLayout.createSequentialGroup() .addGap(10, 10, 10) .addComponent(jLabel2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(localDir, javax.swing.GroupLayout.DEFAULT_SIZE, 227, Short.MAX_VALUE)) .addComponent(split_local, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 295, Short.MAX_VALUE) ); localSideLayout.setVerticalGroup( localSideLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(localSideLayout.createSequentialGroup() .addGroup(localSideLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(localDir, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel2)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(split_local, javax.swing.GroupLayout.DEFAULT_SIZE, 270, Short.MAX_VALUE)) ); split_files.setLeftComponent(localSide); remoteSide.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED)); jLabel1.setText("Remote site:"); remoteDir.setEditable(false); remoteDir.setText("/"); split_remote.setDividerLocation(200); split_remote.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); treeNode1 = new javax.swing.tree.DefaultMutableTreeNode("root"); remoteTree.setModel(new javax.swing.tree.DefaultTreeModel(treeNode1)); remoteTree.setComponentPopupMenu(remoteMenu); remoteTree.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { remoteTreeMouseClicked(evt); } }); jScrollPane1.setViewportView(remoteTree); split_remote.setTopComponent(jScrollPane1); jScrollPane3.setComponentPopupMenu(remoteMenu); remoteFiles.setModel(new javax.swing.table.DefaultTableModel( new Object [][] { {null, null, null, null}, {null, null, null, null}, {null, null, null, null}, {null, null, null, null} }, new String [] { "Title 1", "Title 2", "Title 3", "Title 4" } )); remoteFiles.setComponentPopupMenu(remoteMenu); remoteFiles.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { remoteFilesMouseClicked(evt); } }); remoteFiles.addKeyListener(new java.awt.event.KeyAdapter() { public void keyPressed(java.awt.event.KeyEvent evt) { remoteFilesKeyPressed(evt); } }); jScrollPane3.setViewportView(remoteFiles); split_remote.setRightComponent(jScrollPane3); javax.swing.GroupLayout remoteSideLayout = new javax.swing.GroupLayout(remoteSide); remoteSide.setLayout(remoteSideLayout); remoteSideLayout.setHorizontalGroup( remoteSideLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(remoteSideLayout.createSequentialGroup() .addGap(10, 10, 10) .addComponent(jLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(remoteDir, javax.swing.GroupLayout.DEFAULT_SIZE, 273, Short.MAX_VALUE)) .addComponent(split_remote, javax.swing.GroupLayout.DEFAULT_SIZE, 348, Short.MAX_VALUE) ); remoteSideLayout.setVerticalGroup( remoteSideLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(remoteSideLayout.createSequentialGroup() .addGroup(remoteSideLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(remoteDir, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel1)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(split_remote, javax.swing.GroupLayout.DEFAULT_SIZE, 270, Short.MAX_VALUE)) ); split_files.setRightComponent(remoteSide); split_main.setLeftComponent(split_files); status.setText("Status..."); abort.setText("Abort"); abort.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { abortActionPerformed(evt); } }); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(status, javax.swing.GroupLayout.DEFAULT_SIZE, 633, Short.MAX_VALUE) .addComponent(progress, javax.swing.GroupLayout.DEFAULT_SIZE, 633, Short.MAX_VALUE) .addComponent(abort, javax.swing.GroupLayout.Alignment.TRAILING)) .addContainerGap()) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() .addContainerGap() .addComponent(status) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(progress, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(abort) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); status_pane.addTab("File Transfer", jPanel1); log.setColumns(20); log.setEditable(false); log.setRows(5); jScrollPane5.setViewportView(log); javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addContainerGap() .addComponent(jScrollPane5, javax.swing.GroupLayout.DEFAULT_SIZE, 633, Short.MAX_VALUE) .addContainerGap()) ); jPanel2Layout.setVerticalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() .addContainerGap() .addComponent(jScrollPane5, javax.swing.GroupLayout.DEFAULT_SIZE, 79, Short.MAX_VALUE) .addContainerGap()) ); status_pane.addTab("Transfer Log", jPanel2); split_main.setRightComponent(status_pane); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(split_main) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(split_main) ); }// </editor-fold>//GEN-END:initComponents private void remote_downloadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_remote_downloadActionPerformed download(); }//GEN-LAST:event_remote_downloadActionPerformed private void remoteFilesMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_remoteFilesMouseClicked if (evt.getClickCount() != 2) { return; } if (evt.getButton() != 1) { return; } dblclickRemote(); }//GEN-LAST:event_remoteFilesMouseClicked private void localFilesMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_localFilesMouseClicked if (evt.getClickCount() != 2) { return; } if (evt.getButton() != 1) { return; } dblclickLocal(); }//GEN-LAST:event_localFilesMouseClicked private void formComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentResized resize(); }//GEN-LAST:event_formComponentResized private void formComponentShown(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentShown resize(); }//GEN-LAST:event_formComponentShown private void local_uploadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_local_uploadActionPerformed upload(); }//GEN-LAST:event_local_uploadActionPerformed private void local_mkdirActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_local_mkdirActionPerformed local_mkdir(); }//GEN-LAST:event_local_mkdirActionPerformed private void local_refreshActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_local_refreshActionPerformed parseLocal(); }//GEN-LAST:event_local_refreshActionPerformed private void local_deleteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_local_deleteActionPerformed local_delete(); }//GEN-LAST:event_local_deleteActionPerformed private void local_renameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_local_renameActionPerformed local_rename(); }//GEN-LAST:event_local_renameActionPerformed private void remote_mkdirActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_remote_mkdirActionPerformed remote_mkdir(); }//GEN-LAST:event_remote_mkdirActionPerformed private void remote_refreshActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_remote_refreshActionPerformed remote_chdir("."); }//GEN-LAST:event_remote_refreshActionPerformed private void remote_deleteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_remote_deleteActionPerformed remote_delete(); }//GEN-LAST:event_remote_deleteActionPerformed private void remote_renameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_remote_renameActionPerformed remote_rename(); }//GEN-LAST:event_remote_renameActionPerformed private void remote_propsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_remote_propsActionPerformed remote_props(); }//GEN-LAST:event_remote_propsActionPerformed private void remoteTreeMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_remoteTreeMouseClicked if (evt.getClickCount() != 2) { return; } if (evt.getButton() != 1) { return; } dblclickRemoteTree(); }//GEN-LAST:event_remoteTreeMouseClicked private void localTreeMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_localTreeMouseClicked if (evt.getClickCount() != 2) { return; } if (evt.getButton() != 1) { return; } dblclickLocalTree(); }//GEN-LAST:event_localTreeMouseClicked private void localFilesKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_localFilesKeyPressed int keycode = evt.getKeyCode(); int mods = evt.getModifiers(); if (mods == KeyEvent.CTRL_MASK) { switch (keycode) { case KeyEvent.VK_C: // local_copy(); break; case KeyEvent.VK_X: // local_cut(); break; case KeyEvent.VK_V: // local_paste(); break; } } if (mods == 0) { if (keycode == KeyEvent.VK_DELETE) { local_delete(); } } }//GEN-LAST:event_localFilesKeyPressed private void remoteFilesKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_remoteFilesKeyPressed int keycode = evt.getKeyCode(); int mods = evt.getModifiers(); if (mods == KeyEvent.CTRL_MASK) { switch (keycode) { case KeyEvent.VK_C: // remote_copy(); break; case KeyEvent.VK_X: // remote_cut(); break; case KeyEvent.VK_V: // remote_paste(); break; } } if (mods == 0) { if (keycode == KeyEvent.VK_DELETE) { remote_delete(); } } }//GEN-LAST:event_remoteFilesKeyPressed private void abortActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_abortActionPerformed abort(); }//GEN-LAST:event_abortActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton abort; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel2; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JScrollPane jScrollPane2; private javax.swing.JScrollPane jScrollPane3; private javax.swing.JScrollPane jScrollPane4; private javax.swing.JScrollPane jScrollPane5; private javax.swing.JPopupMenu.Separator jSeparator1; private javax.swing.JPopupMenu.Separator jSeparator2; private javax.swing.JPopupMenu.Separator jSeparator4; private javax.swing.JPopupMenu.Separator jSeparator5; private javax.swing.JPopupMenu.Separator jSeparator6; public javax.swing.JTextField localDir; public javax.swing.JTable localFiles; private javax.swing.JPopupMenu localMenu; private javax.swing.JPanel localSide; private javax.swing.JTree localTree; private javax.swing.JMenuItem local_delete; private javax.swing.JMenuItem local_mkdir; private javax.swing.JMenuItem local_refresh; private javax.swing.JMenuItem local_rename; private javax.swing.JMenuItem local_upload; private javax.swing.JTextArea log; public javax.swing.JProgressBar progress; public javax.swing.JTextField remoteDir; public javax.swing.JTable remoteFiles; private javax.swing.JPopupMenu remoteMenu; private javax.swing.JPanel remoteSide; private javax.swing.JTree remoteTree; private javax.swing.JMenuItem remote_delete; private javax.swing.JMenuItem remote_download; private javax.swing.JMenuItem remote_mkdir; private javax.swing.JMenuItem remote_props; private javax.swing.JMenuItem remote_refresh; private javax.swing.JMenuItem remote_rename; private javax.swing.JSplitPane split_files; private javax.swing.JSplitPane split_local; private javax.swing.JSplitPane split_main; private javax.swing.JSplitPane split_remote; public javax.swing.JLabel status; private javax.swing.JTabbedPane status_pane; // End of variables declaration//GEN-END:variables public XML localFolders = new XML(); public XML remoteFolders = new XML(); public int totalFileSize = 0; private static ImageIcon ii[] = new ImageIcon[24]; private static final int PIC_FOLDER = 0; private static final int PIC_LINK = 1; private static final int PIC_FILE = 2; private static String icons[] = { "folder.png", "link.png", "file.png" }; public DefaultTableModel localFilesTableModel = new DefaultTableModel(); public DefaultTableModel remoteFilesTableModel = new DefaultTableModel(); private DefaultTableColumnModel localFilesTableColumnModel = new DefaultTableColumnModel(); private DefaultTableColumnModel remoteFilesTableColumnModel = new DefaultTableColumnModel(); public boolean aborted = false; public abstract boolean connect(SiteDetails sd); public abstract void disconnect(); public abstract void remote_chdir(String path); public abstract void remote_mkdir(); public abstract void remote_delete(); public abstract void remote_rename(); public abstract void remote_props(); public abstract void download(); public abstract void upload(); public abstract void abort(); public ArrayList<String> localFolderStack; //used for moving in/out folders (in case a folder is a sym-link) public ArrayList<String> remoteFolderStack; //used for moving in/out folders (in case a folder is a sym-link) private TableCellRenderer tableCellRenderer = new TableCellRenderer() { public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { //each Object 'is' a JLabel (Contact) which makes this easy if (value == null) { return new JLabel("null"); } JLabel label; if (value instanceof String) { label = new JLabel((String) value); } else { label = (JLabel) value; } if (isSelected) { label.setBackground(table.getSelectionBackground()); label.setForeground(table.getSelectionForeground()); } else { label.setBackground(table.getBackground()); label.setForeground(table.getForeground()); } label.setEnabled(table.isEnabled()); label.setFont(table.getFont()); label.setOpaque(true); return label; } }; private TableCellEditor tableCellEditor = new DefaultCellEditor(new JTextField("")) { @Override public boolean isCellEditable(EventObject anEvent) { return false; //BUG : inline editing doesn't work yet } @Override public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { String str = ""; if (value instanceof JLabel) { str = ((JLabel) value).getText(); } if (value instanceof String) { str = (String) value; } return new JTextField(str); } }; protected static class SiteFile extends javax.swing.JLabel implements Comparable { public SiteFile(String label, int filesize, int type, String link) { super(label); this.filesize = filesize; setIcon(ii[type]); switch (type) { case PIC_FOLDER: isDir = true; break; case PIC_LINK: isLink = true; if (link.endsWith("/")) { isDir = true; } break; } this.link = link; } public int filesize; public boolean isDir = false; public boolean isLink = false; public String link = ""; public int compareTo(Object o) { SiteFile sf = (SiteFile) o; //place folders first if (sf.isDir && !isDir) { return 1; } if (!sf.isDir && isDir) { return -1; } return getText().compareTo(sf.getText()); } } private static class LocalFileSorter implements Comparable { public LocalFileSorter(File file) { this.file = file; } public File file; public int compareTo(Object o) { LocalFileSorter that = (LocalFileSorter) o; //place folders first if (that.file.isDirectory() && !file.isDirectory()) { return 1; } if (!that.file.isDirectory() && file.isDirectory()) { return -1; } return file.getName().compareTo(that.file.getName()); } } private static class RemoteFileSorter implements Comparable { public RemoteFileSorter(String fs[]) { this.fs = fs; } public String fs[]; public boolean isDirectory() { return fs[0].charAt(0) == 'd'; } public boolean isLink() { return fs[0].charAt(0) == 'l'; } public int compareTo(Object o) { RemoteFileSorter that = (RemoteFileSorter) o; //place folders first if (that.isDirectory() && !isDirectory()) { return 1; } if (!that.isDirectory() && isDirectory()) { return -1; } return fs[8].compareTo(that.fs[8]); } } public static void loadIcons(Class cls) { for (int a = 0; a < icons.length; a++) { try { InputStream is = cls.getClassLoader().getResourceAsStream(icons[a]); int len = is.available(); byte data[] = new byte[len]; is.read(data); is.close(); ii[a] = new ImageIcon(data); } catch (Exception e) { JFLog.log("err:loadIcons() Failed:" + e); } } } public void init(String initLocalDir) { if (initLocalDir.length() > 0) { localDir.setText(initLocalDir.replaceAll("\\\\", "/")); } TableColumn tc; localFolders.setTag(localFolders.root, "/", "", ""); localTree.setModel(localFolders.getTreeModel()); remoteFolders.setTag(remoteFolders.root, "/", "", ""); remoteTree.setModel(remoteFolders.getTreeModel()); tc = new TableColumn(0, 50, tableCellRenderer, tableCellEditor); tc.setHeaderRenderer(tableCellRenderer); tc.setHeaderValue(new JLabel("file")); localFilesTableColumnModel.addColumn(tc); tc = new TableColumn(1, 50, tableCellRenderer, tableCellEditor); tc.setHeaderRenderer(tableCellRenderer); tc.setHeaderValue(new JLabel("size")); localFilesTableColumnModel.addColumn(tc); tc = new TableColumn(2, 50, tableCellRenderer, tableCellEditor); tc.setHeaderRenderer(tableCellRenderer); tc.setHeaderValue(new JLabel("date")); localFilesTableColumnModel.addColumn(tc); tc = new TableColumn(0, 50, tableCellRenderer, tableCellEditor); tc.setHeaderRenderer(tableCellRenderer); tc.setHeaderValue(new JLabel("file")); remoteFilesTableColumnModel.addColumn(tc); tc = new TableColumn(1, 50, tableCellRenderer, tableCellEditor); tc.setHeaderRenderer(tableCellRenderer); tc.setHeaderValue(new JLabel("size")); remoteFilesTableColumnModel.addColumn(tc); tc = new TableColumn(2, 50, tableCellRenderer, tableCellEditor); tc.setHeaderRenderer(tableCellRenderer); tc.setHeaderValue(new JLabel("date")); remoteFilesTableColumnModel.addColumn(tc); tc = new TableColumn(3, 50, tableCellRenderer, tableCellEditor); tc.setHeaderRenderer(tableCellRenderer); tc.setHeaderValue(new JLabel("permissions")); remoteFilesTableColumnModel.addColumn(tc); tc = new TableColumn(4, 50, tableCellRenderer, tableCellEditor); tc.setHeaderRenderer(tableCellRenderer); tc.setHeaderValue(new JLabel("owner/group")); remoteFilesTableColumnModel.addColumn(tc); localFilesTableModel.addColumn("file"); localFilesTableModel.addColumn("size"); localFilesTableModel.addColumn("date"); localFiles.setModel(localFilesTableModel); localFiles.setColumnModel(localFilesTableColumnModel); localFiles.setShowGrid(false); remoteFilesTableModel.addColumn("file"); remoteFilesTableModel.addColumn("size"); remoteFilesTableModel.addColumn("date"); remoteFilesTableModel.addColumn("permissions"); remoteFilesTableModel.addColumn("owner/group"); remoteFiles.setModel(remoteFilesTableModel); remoteFiles.setColumnModel(remoteFilesTableColumnModel); remoteFiles.setShowGrid(false); if (JF.isWindows()) { parseLocalRootWindows(); } parseLocal(); setState(true); } private void parseLocalRootWindows() { localFilesTableModel.setRowCount(0); for (char drv = 'a'; drv <= 'z'; drv++) { try { File test = new File("" + drv + ":\\"); if (!test.exists()) { continue; } localFilesTableModel.addRow(new Object[]{new SiteFile("" + drv + ":", 0, PIC_FOLDER, ""), "", ""}); XML.XMLTag tag = localFolders.addSetTag(localFolders.root, "" + drv + ":", "", ""); localTree.expandPath(new TreePath(tag.getPath())); } catch (Exception e) { } } localTree.setSelectionPath(new TreePath(localFolders.root.getPath())); } public XML.XMLTag localTag; private void parseLocal() { String wd = localDir.getText().replaceAll("\\\\", "/"); if (JF.isWindows() && wd.equals("/")) { parseLocalRootWindows(); return; } localFilesTableModel.setRowCount(0); String wds[] = wd.split("/+"); //+=greedy //make sure all folders to current path are in tree localTag = localFolders.root; localTree.expandPath(new TreePath(localTag.getPath())); for (int a = 0; a < wds.length; a++) { if (wds[a].length() == 0) { continue; } localTag = localFolders.addSetTag(localTag, wds[a], "", ""); localTree.expandPath(new TreePath(localTag.getPath())); // showPath("local", tag.getPath()); } localTree.setSelectionPath(new TreePath(localTag.getPath())); if (!wd.equals("/")) { //add ".." entry localFilesTableModel.addRow(new Object[]{ new SiteFile("..", 0, PIC_FOLDER, ""), "", "" }); } try { File spec = new File(wd); File files[] = spec.listFiles(); if ((files == null) || (files.length == 0)) { return; } LocalFileSorter sortedFiles[] = new LocalFileSorter[files.length]; for (int idx = 0; idx < files.length; idx++) { sortedFiles[idx] = new LocalFileSorter(files[idx]); } Arrays.sort(sortedFiles); for (int idx = 0; idx < sortedFiles.length; idx++) { String fn = sortedFiles[idx].file.getName(); int size = (int) sortedFiles[idx].file.length(); Date lm = new Date(sortedFiles[idx].file.lastModified()); String date = new SimpleDateFormat("yyyy-MM-dd kk:mm").format(lm); if (sortedFiles[idx].file.isDirectory()) { localFilesTableModel.addRow(new Object[]{ new SiteFile(fn, 0, PIC_FOLDER, ""), "" + size, date }); if (fn.equals("..")) { continue; } localFolders.addSetTag(localTag, fn, "", ""); } else { localFilesTableModel.addRow(new Object[]{ new SiteFile(fn, 0, PIC_FILE, ""), "" + size, date }); } } } catch (Exception e) { setStatus("Error:" + e); JFLog.log(e); addLog("Error:" + e); } } public XML.XMLTag remoteTag; public void parseRemote(String wd, String ls) { //drwxr-xr-x 3 0 0 4096 Jan 03 20:48 .. //attr node owner group filesize mth dy time filename //time=year if older than 1 year // ls = ls.replaceAll("\t", " "); String wds[] = wd.split("/+"); //+=greedy //make sure all folders to current path are in tree remoteTag = remoteFolders.root; remoteTree.expandPath(new TreePath(remoteTag.getPath())); for (int a = 0; a < wds.length; a++) { if (wds[a].length() == 0) { continue; } remoteTag = remoteFolders.addSetTag(remoteTag, wds[a], "", ""); remoteTree.expandPath(new TreePath(remoteTag.getPath())); // showPath("remote", tag.getPath()); } remoteTree.setSelectionPath(new TreePath(remoteTag.getPath())); String files[] = ls.replaceAll("\r", "").split("\n"); RemoteFileSorter sortedFiles[] = new RemoteFileSorter[files.length]; for (int a = 0; a < files.length; a++) { //JFLog.log("files[]=" + files[a]); //TEST if (files[a].length() == 0) { continue; } String fs[] = new String[10]; for (int b = 0; b < 8; b++) { files[a] = files[a].trim(); int idx = files[a].indexOf(" "); if (idx == -1) { idx = files[a].length(); } fs[b] = files[a].substring(0, idx); files[a] = files[a].substring(fs[b].length() + 1); } fs[8] = files[a]; //what's left is filename if (fs[0].charAt(0) == 'l') { //parse link info int idx = fs[8].indexOf("->"); if (idx == -1) { fs[9] = "?"; // JFLog.log("unknown link:" + fs[8]); } else { fs[9] = fs[8].substring(idx + 3); fs[8] = fs[8].substring(0, idx - 1); // JFLog.log("link:" + fs[8] + " -> " + fs[9]); } } else { fs[9] = ""; } sortedFiles[a] = new RemoteFileSorter(fs); } Arrays.sort(sortedFiles); remoteFilesTableModel.setRowCount(0); for (int a = 0; a < sortedFiles.length; a++) { if (sortedFiles[a] == null) { continue; } String fs[] = sortedFiles[a].fs; //fs[0] == attr //fs[1] == node //fs[2] == owner //fs[3] == group //fs[4] == filesize //fs[5] == month //fs[6] == day //fs[7] == time(HH:MM) or year //fs[8] == filename //fs[9] == link target (if link) if (fs[0].length() != 10) { continue; } if (fs[8].equals(".")) { continue; } if (fs[8].equals("..") && wd.equals("/")) { continue; } switch (fs[0].charAt(0)) { case 'd': //directory remoteFilesTableModel.addRow(new Object[]{ new SiteFile(fs[8], 0, PIC_FOLDER, ""), "" + fs[4], "" + fs[5] + "," + fs[6] + " " + fs[7], "" + fs[0], "" + fs[2] + "/" + fs[3] }); if (fs[8].equals("..")) { break; } remoteFolders.addSetTag(remoteTag, fs[8], "", ""); break; case 'l': //link remoteFilesTableModel.addRow(new Object[]{ new SiteFile(fs[8], 0, PIC_LINK, fs[9]), "" + fs[4], "" + fs[5] + "," + fs[6] + " " + fs[7], "" + fs[0], "" + fs[2] + "/" + fs[3] }); break; default: remoteFilesTableModel.addRow(new Object[]{ new SiteFile(fs[8], Integer.valueOf(fs[4]), PIC_FILE, ""), "" + fs[4], "" + fs[5] + "," + fs[6] + " " + fs[7], "" + fs[0], "" + fs[2] + "/" + fs[3] }); break; } } progress.setValue(0); //listing is actually a file transfer } public void local_chdir(String path) { String wd = localDir.getText(); path = path.replaceAll("\\\\", "/"); if (path.equals(".")) { //do nothing } else if (path.equals("..")) { //remove last path element int idx = wd.lastIndexOf('/'); if (idx == -1) { wd = "/"; } else { if (JF.isWindows() && wd.length() == 3) { wd = "/"; } else { wd = wd.substring(0, idx); } if (JF.isWindows()) { if (wd.length() == 2) { wd += "/"; } } } } else { if ((path.length() == 2) && (path.charAt(1) == ':')) { wd = path + "/"; } else { if (path.indexOf("/") != -1) { //absolute path wd = path; } else { //add path element if (JF.isWindows() && wd.equals("/")) { wd = path + "/"; } else { if (!wd.endsWith("/")) { wd += "/"; } wd += path; } } } } localDir.setText(wd); parseLocal(); } public void addLog(String msg) { String old = log.getText(); if (old.length() == 0) { log.setText(msg); } else { log.setText(old + "\r\n" + msg); } log.setCaretPosition(log.getText().length() - 1); } public void setState(boolean state) { localDir.setEnabled(state); remoteDir.setEnabled(state); localTree.setEnabled(state); localFiles.setEnabled(state); remoteTree.setEnabled(state); remoteFiles.setEnabled(state); abort.setVisible(!state); progress.setValue(0); } public void setTotalFileSize(int value) { // System.out.println("setTotalFileSize:" + value); totalFileSize = value; setProgress(0); } private int progressPercent = 0; public void setProgress(int value) { float x = value; float y = totalFileSize; int newPercent = (int) (x / y * 100.0f); if (newPercent == progressPercent) return; progressPercent = newPercent; // System.out.println("setProgress:" + newPercent); java.awt.EventQueue.invokeLater(new Runnable() { public void run() { progress.setValue(progressPercent); } }); } public void resize() { int w = this.getWidth(); int h = this.getHeight(); h -= status_pane.getPreferredSize().height; split_main.setDividerLocation(h); split_files.setDividerLocation(w / 2); split_local.setDividerLocation(h / 2); split_remote.setDividerLocation(h / 2); } public void local_mkdir() { String fn = JF.getString("Enter new folder name", ""); if ((fn == null) || (fn.length() == 0)) { return; } if (fn.indexOf(":") != -1) { return; } if (fn.indexOf("/") != -1) { return; } if (fn.indexOf("?") != -1) { return; } if (fn.indexOf("*") != -1) { return; } String wd = localDir.getText(); if (!wd.endsWith("/")) { wd += "/"; } try { local_mkdir(wd + fn); localFolders.addSetTag(localTag, fn, "", ""); local_chdir("."); //refresh } catch (Exception e) { JF.showError("Error", "Create folder failed:" + e); } } public void local_mkdir(String path) { File file = new File(path); file.mkdir(); } public void local_delete() { if (!JF.showConfirm("Delete", "Are you sure you want to delete file(s)?")) { return; } aborted = false; localFolderStack = new ArrayList<String>(); local_delete_files(); local_chdir("."); //refresh } private void local_delete_files() { int rows[] = localFiles.getSelectedRows(); if (rows.length == 0) { return; } SiteFile sf[] = new SiteFile[rows.length]; for (int idx = 0; idx < rows.length; idx++) { sf[idx] = (SiteFile) localFilesTableModel.getValueAt(rows[idx], 0); } for (int idx = 0; idx < sf.length; idx++) { if (sf[idx].getText().equals(".")) { continue; } if (sf[idx].getText().equals("..")) { continue; } totalFileSize = sf[idx].filesize; if (sf[idx].isDir) { localFolderStack.add(localDir.getText()); local_chdir(sf[idx].getText()); } if (sf[idx].isLink && !sf[idx].isDir) { //test if dir String d1 = localDir.getText(); local_chdir(sf[idx].getText()); String d2 = localDir.getText(); if (!d1.equals(d2)) { localFolderStack.add(d1); sf[idx].isDir = true; } } if (sf[idx].isDir) { //already local_chdir localFiles.selectAll(); local_delete_files(); local_chdir(localFolderStack.remove(localFolderStack.size() - 1)); } File localFile = new File(localDir.getText() + "/" + sf[idx].getText()); local_delete_file(localFile); if (aborted) { break; } } } private void local_delete_file(File file) { try { file.delete(); //update localTree for (int a = 0; a < localTag.getChildCount(); a++) { XML.XMLTag child = localTag.getChildAt(a); if (child.getName().equals(file.getName())) { localFolders.deleteTag(child); break; } } } catch (Exception e) { setStatus("Error:" + e); JFLog.log(e); addLog("Error:" + e); } } public void local_rename() { int rows[] = localFiles.getSelectedRows(); if ((rows == null) || (rows.length != 1)) { return; } SiteFile sf = (SiteFile) localFilesTableModel.getValueAt(rows[0], 0); File localFile = new File(localDir.getText() + "/" + sf.getText()); String newName = JF.getString("Rename " + (localFile.isDirectory() ? "Folder" : "File"), sf.getText()); if ((newName == null) || (newName.length() == 0)) { return; } File newFile = new File(localDir.getText() + "/" + newName); localFile.renameTo(newFile); //update localTree for (int a = 0; a < localTag.getChildCount(); a++) { XML.XMLTag child = localTag.getChildAt(a); if (child.getName().equals(sf.getText())) { child.setName(newName); break; } } local_chdir("."); //refresh } public void setStatus(String str) { if (str == null) { setState(true); status.setText("Idle"); } else { setState(false); status.setText(str); } } private void showPath(String name, Object path[]) { System.out.println(name); for (int a = 0; a < path.length; a++) { System.out.println("path[]=" + path[a]); } } private void dblclickLocal() { //dbl click local int rows[] = localFiles.getSelectedRows(); if (rows.length != 1) { return; } SiteFile sf = (SiteFile) localFilesTableModel.getValueAt(rows[0], 0); if (!sf.isDir) { upload(); } else { local_chdir(sf.getText()); } } private void dblclickRemote() { //dbl click remote int rows[] = remoteFiles.getSelectedRows(); if (rows.length != 1) { return; } SiteFile sf = (SiteFile) remoteFilesTableModel.getValueAt(rows[0], 0); if (sf.isLink && !sf.isDir) { //test if folder String d1 = remoteDir.getText(); remote_chdir(sf.getText()); String d2 = remoteDir.getText(); if (!d1.equals(d2)) { sf.isDir = true; return; } } if (!sf.isDir) { download(); } else { remote_chdir(sf.getText()); } } private void dblclickLocalTree() { TreePath paths[] = localTree.getSelectionPaths(); if (paths.length != 1) { return; } XML.XMLTag tag = localFolders.getTag(paths[0]); ArrayList<String> pathElements = new ArrayList<String>(); do { if (tag.getName().equals("/")) { break; //top node } pathElements.add(0, tag.getName()); //insert at top tag = tag.getParent(); } while (tag != null); String fullPath = ""; for (int a = 0; a < pathElements.size(); a++) { if (!((fullPath.length() == 0) && (JF.isWindows()))) { if (!fullPath.endsWith("/")) { fullPath += "/"; } } fullPath += pathElements.get(a); } if (fullPath.equals("")) { fullPath = "/"; } local_chdir(fullPath); } private void dblclickRemoteTree() { TreePath paths[] = remoteTree.getSelectionPaths(); if (paths.length != 1) { return; } XML.XMLTag tag = remoteFolders.getTag(paths[0]); ArrayList<String> pathElements = new ArrayList<String>(); do { if (tag.getName().equals("/")) { break; //top node } pathElements.add(0, tag.getName()); //insert at top tag = tag.getParent(); } while (tag != null); String fullPath = ""; for (int a = 0; a < pathElements.size(); a++) { if (!fullPath.endsWith("/")) { fullPath += "/"; } fullPath += pathElements.get(a); } if (fullPath.equals("")) { fullPath = "/"; } remote_chdir(fullPath); } }