/* * Copyright 2012 jMethods, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.myjavaworld.jftp; import java.awt.Component; import java.awt.Cursor; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.text.MessageFormat; import java.util.Arrays; import java.util.Date; import java.util.Locale; import java.util.ResourceBundle; import javax.swing.DefaultComboBoxModel; import javax.swing.Icon; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JTable; import javax.swing.KeyStroke; import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; import javax.swing.TransferHandler; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import com.myjavaworld.ftp.RemoteFile; import com.myjavaworld.gui.DateCellRenderer; import com.myjavaworld.gui.GUIUtil; import com.myjavaworld.gui.MButton; import com.myjavaworld.gui.MComboBox; import com.myjavaworld.gui.MLabel; import com.myjavaworld.gui.MScrollPane; import com.myjavaworld.gui.MTable; import com.myjavaworld.gui.MTableCellRenderer; import com.myjavaworld.gui.MTableHeaderRenderer; import com.myjavaworld.gui.NumericCellRenderer; import com.myjavaworld.jftp.actions.DeleteRemoteFileAction; import com.myjavaworld.jftp.actions.OpenRemoteFileAction; import com.myjavaworld.util.ResourceLoader; /** * Remote file system view. * * @author Sai Pullabhotla, psai [at] jMethods [dot] com * @version 2.0 * */ public class RemotePane extends JPanel implements ActionListener, MouseListener, ListSelectionListener { private static ResourceBundle resources = ResourceLoader .getBundle("com.myjavaworld.jftp.RemotePane"); private static final Icon UP_ARROW_ICON = JFTPUtil.getIcon("upArrow16.gif"); private static final Icon DOWN_ARROW_ICON = JFTPUtil .getIcon("downArrow16.gif"); private FTPSession session = null; private MComboBox comboWorkingDirectory = null; private MButton butUp = null; private RemoteFileTableModel model = null; private MTable table = null; private MScrollPane scroller = null; private MLabel labStatus = null; private RemoteFileComparator comparator = null; private boolean updateComboWorkingDirectory = true; private MessageFormat statusFormat1 = null; private MessageFormat statusFormat2 = null; private Object[] statusArgs = null; public RemotePane(FTPSession session) { super(); this.session = session; comparator = new RemoteFileComparator(); statusFormat1 = new MessageFormat( resources.getString("status.objectCount")); statusFormat2 = new MessageFormat( resources.getString("status.selectedObjectCount")); statusFormat1.setLocale(Locale.getDefault()); statusFormat2.setLocale(Locale.getDefault()); statusArgs = new Object[2]; setLayout(new GridBagLayout()); initComponents(); configureTable(); updateTableHeader(); } public void setData(RemoteFile dir, RemoteFile[] data) { if (data == null) { data = new RemoteFile[0]; } Arrays.sort(data, comparator); model.setData(data); if (updateComboWorkingDirectory) { updateComboWorkingDirectory(dir); } if (data.length > 0) { table.scrollRectToVisible(table.getCellRect(0, 0, true)); } updateStatus(); } public RemoteFile[] getData() { return model.getData(); } public int getSelectionCount() { return table.getSelectedRowCount(); } public RemoteFile getSelectedFile() { int row = table.getSelectedRow(); if (row < 0) { return null; } return model.getFileAt(row); } public RemoteFile[] getSelectedFiles() { int[] selectedRows = table.getSelectedRows(); if (selectedRows == null) { return new RemoteFile[0]; } RemoteFile[] selectedFiles = new RemoteFile[selectedRows.length]; for (int i = 0; i < selectedRows.length; i++) { selectedFiles[i] = model.getFileAt(selectedRows[i]); } return selectedFiles; } public void refresh() { session.setRemoteWorkingDirectory(session.getRemoteWorkingDirectory()); } public void clearAll() { comboWorkingDirectory.setModel(new DefaultComboBoxModel()); model.setData(new RemoteFile[0]); } public void valueChanged(ListSelectionEvent evt) { updateStatus(); session.updateToolBar(); } public void actionPerformed(ActionEvent evt) { if (evt.getSource() == butUp) { session.upRemoteWorkingDirectory(); } else if (evt.getSource() == comboWorkingDirectory) { RemoteFile selectedFile = (RemoteFile) comboWorkingDirectory .getSelectedItem(); updateComboWorkingDirectory = false; session.setRemoteWorkingDirectory(selectedFile); updateComboWorkingDirectory = true; } } public void mouseEntered(MouseEvent evt) { } public void mouseExited(MouseEvent evt) { } public void mousePressed(MouseEvent evt) { if (evt.isPopupTrigger()) { if (evt.getSource() == table) { tableRightClicked(evt); } else if (evt.getSource() == scroller) { scrollerRightClicked(evt); } } } public void mouseReleased(MouseEvent evt) { if (evt.isPopupTrigger()) { if (evt.getSource() == table) { tableRightClicked(evt); } else if (evt.getSource() == scroller) { scrollerRightClicked(evt); } } else if (evt.getSource() == table) { if (SwingUtilities.isLeftMouseButton(evt) && evt.getClickCount() >= 2) { doubleClicked(evt); } } else if (evt.getSource() == table.getTableHeader()) { if (SwingUtilities.isLeftMouseButton(evt)) { Cursor cursor = table.getTableHeader().getCursor(); if (cursor.equals(Cursor .getPredefinedCursor(Cursor.DEFAULT_CURSOR))) { int column = table.columnAtPoint(evt.getPoint()); column = table.convertColumnIndexToModel(column); if (column < 4) { sort(column); } } } } } public void mouseClicked(MouseEvent evt) { } private void tableRightClicked(MouseEvent evt) { JPopupMenu popup = RemoteSystemPopupMenu.getInstance(session.getJFTP()); popup.show((Component) evt.getSource(), evt.getX(), evt.getY()); } private void scrollerRightClicked(MouseEvent evt) { table.clearSelection(); JPopupMenu popup = RemoteSystemPopupMenu.getInstance(session.getJFTP()); popup.show((Component) evt.getSource(), evt.getX(), evt.getY()); } private void doubleClicked(MouseEvent evt) { int row = table.rowAtPoint(evt.getPoint()); if (row < 0) { return; } RemoteFile file = model.getFileAt(row); if (file.isDirectory() || file.isLink()) { session.setRemoteWorkingDirectory(file); } else { OpenRemoteFileAction.getInstance(session.getJFTP()) .actionPerformed(null); } } private void updateComboWorkingDirectory(RemoteFile dir) { comboWorkingDirectory.removeActionListener(this); int count = comboWorkingDirectory.getItemCount(); for (int i = 0; i < count; i++) { if (dir.equals(comboWorkingDirectory.getItemAt(i))) { comboWorkingDirectory.setSelectedIndex(i); comboWorkingDirectory.addActionListener(this); return; } } comboWorkingDirectory.insertItemAt(dir, 0); comboWorkingDirectory.setSelectedIndex(0); comboWorkingDirectory.addActionListener(this); } private void updateStatus() { long size = 0L; int count = table.getSelectedRowCount(); if (count > 0) { int[] selectedRows = table.getSelectedRows(); for (int i = 0; i < selectedRows.length; i++) { size += model.getFileAt(selectedRows[i]).getSize(); } statusArgs[0] = new Integer(count); statusArgs[1] = new Long(size); labStatus.setText(statusFormat2.format(statusArgs)); return; } count = model.getRowCount(); for (int i = 0; i < count; i++) { size += model.getFileAt(i).getSize(); } statusArgs[0] = new Integer(count); statusArgs[1] = new Long(size); labStatus.setText(statusFormat1.format(statusArgs)); } private void sort(int col) { int compareBy = comparator.getCompareBy(); int order = comparator.getOrder(); if (compareBy == col + 1) { order = order == RemoteFileComparator.ASC_ORDER ? RemoteFileComparator.DESC_ORDER : RemoteFileComparator.ASC_ORDER; } else { compareBy = col + 1; order = RemoteFileComparator.ASC_ORDER; } comparator.setCompareBy(compareBy); comparator.setOrder(order); RemoteFile[] data = model.getData(); Arrays.sort(model.getData(), comparator); model.setData(data); updateTableHeader(); } private void updateTableHeader() { int compareBy = comparator.getCompareBy(); int order = comparator.getOrder(); Icon icon = order == RemoteFileComparator.ASC_ORDER ? UP_ARROW_ICON : DOWN_ARROW_ICON; for (int i = 0; i < 4; i++) { MTableHeaderRenderer r = new MTableHeaderRenderer(); if (compareBy - 1 == i) { r.setIcon(icon); } else { r.setIcon(null); } table.getColumnModel().getColumn(table.convertColumnIndexToView(i)) .setHeaderRenderer(r); } } private void initComponents() { GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.HORIZONTAL; comboWorkingDirectory = new MComboBox(); comboWorkingDirectory.setToolTipText(resources .getString("tooltip.workingDirectory")); comboWorkingDirectory.addActionListener(this); c.gridx = 0; c.gridy = 0; c.gridwidth = 3; c.weightx = 1.0; c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(2, 0, 2, 2); add(comboWorkingDirectory, c); // butUp = new MButton(UIManager.getIcon("FileChooser.upFolderIcon")); butUp = new MButton(JFTPUtil.getIcon("upDirectory16.gif")); butUp.setToolTipText(resources.getString("tooltip.up")); butUp.addActionListener(this); c.gridx = 3; c.gridy = 0; c.gridwidth = 1; c.weightx = 0.0; c.fill = GridBagConstraints.NONE; c.insets = new Insets(2, 0, 2, 0); add(butUp, c); model = new RemoteFileTableModel(); table = new MTable(model) { @Override public boolean getScrollableTracksViewportWidth() { return getPreferredSize().width < getParent().getWidth(); } }; table.setShowGrid(false); table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); scroller = new MScrollPane(table); if (table.isBackgroundSet()) { scroller.getViewport().setBackground(table.getBackground()); } c.gridx = 0; c.gridy = 1; c.gridwidth = 4; c.weightx = 1.0; c.weighty = 1.0; c.fill = GridBagConstraints.BOTH; c.insets = new Insets(0, 0, 2, 0); add(scroller, c); labStatus = new MLabel(" "); c.gridx = 0; c.gridy = 2; c.gridwidth = 4; c.weightx = 1.0; c.weighty = 0.0; c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(0, 5, 2, 0); add(labStatus, c); } private void configureTable() { table.setName("remotePane"); scroller.setName("remotePane"); TransferHandler th = new DnDTransferHandler(session.getJFTP()); table.setDragEnabled(true); scroller.setTransferHandler(th); table.setTransferHandler(th); table.getColumnModel().getColumn(0).setPreferredWidth(150); table.getColumnModel().getColumn(1).setPreferredWidth(75); table.getColumnModel().getColumn(2).setPreferredWidth(100); table.getColumnModel().getColumn(3).setPreferredWidth(150); table.getColumnModel().getColumn(4).setPreferredWidth(100); int dateFormat = JFTP.prefs.getDateFormat(); int timeFormat = JFTP.prefs.getTimeFormat(); table.setDefaultRenderer(RemoteFile.class, new RemoteFileCellRenderer()); table.setDefaultRenderer(Long.class, new NumericCellRenderer()); table.setDefaultRenderer(Date.class, new DateCellRenderer(dateFormat, timeFormat)); table.setDefaultRenderer(Object.class, new MTableCellRenderer()); table.addMouseListener(this); scroller.addMouseListener(this); table.getSelectionModel().addListSelectionListener(this); table.getTableHeader().setDefaultRenderer(new MTableHeaderRenderer()); table.getTableHeader().addMouseListener(this); table.registerKeyboardAction( DeleteRemoteFileAction.getInstance(session.getJFTP()), "cmd.deleteRemoteFile", KeyStroke.getKeyStroke(GUIUtil.getDeleteKey(), 0), JComponent.WHEN_FOCUSED); table.registerKeyboardAction( OpenRemoteFileAction.getInstance(session.getJFTP()), "cmd.openRemoteFile", KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), JComponent.WHEN_FOCUSED); } public void selectAll() { table.selectAll(); } public void invertSelection() { int rowCount = model.getRowCount(); ListSelectionModel selectionModel = table.getSelectionModel(); for (int i = 0; i < rowCount; i++) { if (selectionModel.isSelectedIndex(i)) { selectionModel.removeSelectionInterval(i, i); } else { selectionModel.addSelectionInterval(i, i); } } } }