⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filetable.java

📁 MyDownloader 是一款使用 http 协议(RFC 1867)用于下载一个或多个文件到本地的简单易用的收费 Java 程序.使用托拽操作,你可以在一个页面内下载多个文件.在下载文件的过程当中
💻 JAVA
字号:
/*
 * Copyright 2007 JavaAtWork All rights reserved.
 * Use is subject to license terms.
 */
package com.javaatwork.mydownloader;

import java.awt.Component;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.Transferable;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Vector;

import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.MouseInputListener;
import javax.swing.plaf.basic.BasicTableUI;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;

import com.javaatwork.mydownloader.icons.DownIcon;
import com.javaatwork.mydownloader.icons.UpIcon;
import com.javaatwork.mydownloader.listeners.DownloadManager;
import com.javaatwork.mydownloader.listeners.DownloadTransferable;
import com.javaatwork.mydownloader.utils.LocaleManager;

/**
 * The table for showing the files to download. 
 * 
 * @author Johannes Postma
 */
public class FileTable extends JTable implements ClipboardOwner {

	private static final long serialVersionUID = -4313872144516877286L;
	private DownloadFile[] files = null;
	private boolean sortDown = true;
	private JPopupMenu popup = new JPopupMenu();
	private JMenuItem menuItemCopy = null;
	private MyDownloader applet = null;

	/**
	 * Creates a new FileTable.
	 */
	public FileTable(MyDownloader applet, AbstractTableModel model,
			DownloadFile[] files) {

		super(model);
		this.files = files;
		this.applet = applet;

		// needed due to a bug in the JRE
		setUI(new FixedTableUI());

		// sort
		sort(true);
		repaint();
		
		// add the mouselistener needed to show the popup
		// if the tablemodel is full
		addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				maybeShowPopup(e);
			}

			public void mouseReleased(MouseEvent e) {
				maybeShowPopup(e);
			}
		});

		// popup
		menuItemCopy = new JMenuItem(LocaleManager.getInstance().getString("copy"));
		menuItemCopy.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,
				KeyEvent.CTRL_DOWN_MASK));
		popup.add(menuItemCopy);

		// add the actionlistener needed for the paste
		menuItemCopy.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				createClipboardContents();
			}
		});

		addKeyListener(new DownloadKeyListener());

		// initialise code
		setRowHeight(20);
		setShowGrid(false);
		setDefaultRenderer(DownloadFile.class, new FileRenderer());
		getColumnModel().getColumn(0).setHeaderRenderer(
				new TableHeaderRenderer());
		getTableHeader().addMouseListener(new TableMouseAdapter());
		
		
	}

	public void setSelectedRow(int row) {
		
		// set the first row selected
		if (this.getRowCount() > 0) {
			this.getSelectionModel().setSelectionInterval(0,0);
		}
	}
	
	/**
	 * Returns the files to download.
	 * 
	 * @return The files to download.
	 */
	public DownloadFile[] getFilesToDownload() {

		Vector selectedFiles = new Vector();
		int[] selected = this.getSelectedRows();

		for (int i = 0; i < selected.length; i++) {
			
			// necessary !
			// during the download a user can cancel the download of a specific file
			// because the file already exists
			// if the user cancels the whole download and try a fully new download
			// the overwrite must be reset
			files[selected[i]].setOverwrite(true);
			
			selectedFiles.addElement(files[selected[i]]);
		}

		return (DownloadFile[]) selectedFiles
				.toArray(new DownloadFile[selectedFiles.size()]);
	}

	/**
	 * Returns a DownloadFile.
	 * 
	 * @param index The index.
	 * @return The DownloadFile.
	 */
	public DownloadFile getDownloadFile(int index) {
		return (DownloadFile)files[index];
	}
	
	/**
	 * Add the downloaded files to the clipboard.
	 */
	private void createClipboardContents() {
		Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();

		DownloadManager downloadManager = new DownloadManager();
		File[] files = downloadManager.downloadFiles(applet);

		// nothing has to be copied to the clipboard
		if (files == null) {
			return;
		}

		clipboard.setContents(new DownloadTransferable(files), this);
	}

	/**
	 * Sort the files.
	 * 
	 * @param down Ascending.
	 */
	public void sort(final boolean down) {

		// retrieve position of the file focused
		ListSelectionModel rsm = getSelectionModel(); 
		ListSelectionModel csm = getColumnModel().getSelectionModel();
		int anchorRow = rsm.getAnchorSelectionIndex(); 
		int anchorCol = csm.getAnchorSelectionIndex();
		
		boolean anchorSelected = isCellSelected(anchorRow, anchorCol);
		
		DownloadFile anchorFile = null;
		int anchorPosition = -1;
		
		if (anchorSelected) {
			anchorFile  = files[anchorRow];
		}
		
		// list for storing the current selected files
		Vector selectedFiles = new Vector();
		int[] selected = this.getSelectedRows();

		for (int i = 0; i < selected.length; i++) {
			selectedFiles.addElement(files[selected[i]]);
		}

		Arrays.sort(files, new Comparator() {

			public int compare(Object arg0, Object arg1) {
				DownloadFile file1 = (DownloadFile) arg0;
				DownloadFile file2 = (DownloadFile) arg1;

				if (down) {
					return (file1.getFileName().compareTo(file2.getFileName()
							.toString()));
				} else {
					return (file2.getFileName().compareTo(file1.getFileName()
							.toString()));
				}

			}

		});

		// after the sort no files are selected anymore
		// therefore set the old selected files again
		Vector inter = new Vector();

		for (int i = 0; i < selectedFiles.size(); i++) {
			DownloadFile file = (DownloadFile) selectedFiles.elementAt(i);

			for (int j = 0; j < files.length; j++) {
				if (file == files[j]) {
					inter.addElement(new Integer(j));
				}
				
				if (anchorFile == files[j]) {
					anchorPosition = j;
				}
			}
		}
	
		// set the 'old' selected files again
		selectFiles(inter, anchorPosition);
	}

	/**
	 * Set the 'old' selected files
	 * 
	 * @param files An list of Integer objects.
	 * @param anchorPosition The position of the focused file.
	 */
	public void selectFiles(final Vector files, final int anchorPosition) {

		SwingUtilities.invokeLater(new Runnable() {

			public void run() {

				for (int i = 0; i < files.size(); i++) {
					Integer in = (Integer) files.elementAt(i);
					if (i == 0) {
						setRowSelectionInterval(in.intValue(), in.intValue());
					} else {
						addRowSelectionInterval(in.intValue(), in.intValue());
					}
				}
				
				if (anchorPosition != -1) {
					addRowSelectionInterval(anchorPosition, anchorPosition);
				}				
			}
		});
	}

	/** Shows the popup.
	 * 
	 * @param e The MouseEvent.
	 */
	public void maybeShowPopup(MouseEvent e) {
		if (e.isPopupTrigger()) {
			popup.show(e.getComponent(), e.getX(), e.getY());
		}
	}

	/**
	 * Class for encapsulating the mouse events. This class is needed for the
	 * sort of the table.
	 */
	class TableMouseAdapter extends MouseAdapter {

		public void mouseReleased(MouseEvent me) {

			int clickCount = me.getClickCount();

			if (clickCount == 1) {

				if (sortDown == true) {
					sort(false);
					sortDown = false;
				} else {
					sort(true);
					sortDown = true;
				}
				getTableHeader().repaint();
			}
		}
	}

	/**
	 * Class for showing a table header.
	 */
	class TableHeaderRenderer extends DefaultTableCellRenderer implements
			TableCellRenderer {

		private static final long serialVersionUID = -4402478739497433510L;

		// This method is called each time a column header
		// using this renderer needs to be rendered.
		public Component getTableCellRendererComponent(JTable table,
				Object value, boolean isSelected, boolean hasFocus,
				int rowIndex, int colIndex) {

			// Inherit the colors and font from the header component
			if (table != null) {
				JTableHeader header = table.getTableHeader();

				if (header != null) {
					setForeground(header.getForeground());
					setBackground(header.getBackground());
					setFont(header.getFont());
				}
			}
			
			setText(" " + LocaleManager.getInstance().getString("filename"));

			if (files.length > 1) { // was 0
				if (sortDown) {
					setIcon(new DownIcon());
				} else {
					setIcon(new UpIcon());
				}
			} else {
				setIcon(null); // toegevoegd
			}

			setBorder(UIManager.getBorder("TableHeader.cellBorder"));
			setHorizontalTextPosition(JLabel.LEFT);

			return this;
		}
	}

	/**
	 * Due to a bug (6195469) in the JDK the MouseInputHandler must be overriden.
	 */
	private class FixedTableUI extends BasicTableUI {

		private MouseInputHandler handler = new MouseInputHandler() {

			/* (non-Javadoc)
			 * @see javax.swing.plaf.basic.BasicTableUI$MouseInputHandler#mouseDragged(java.awt.event.MouseEvent)
			 */
			public void mouseDragged(MouseEvent e) {
			}

			/* (non-Javadoc)
			 * @see javax.swing.plaf.basic.BasicTableUI$MouseInputHandler#mousePressed(java.awt.event.MouseEvent)
			 */
			public void mousePressed(MouseEvent e) {

				// logic:
				// select a file only if specified file is not already selected  and if a modifier is not pressed
				// if a file is already selected put the focus on the specified file.
				
				if (SwingUtilities.isLeftMouseButton(e)) {
					Point p = e.getPoint();
					final int pressedRow = table.rowAtPoint(p);
	
					boolean alreadySelected = false;
	
					int[] selectedRows = table.getSelectedRows();
	
					for (int i = 0; i < selectedRows.length; i++) {
						if (selectedRows[i] == pressedRow) {
							alreadySelected = true;
							break;
						}
					}
					
					if (!e.isControlDown() && !e.isShiftDown()) {
							
						if (!alreadySelected) {
							
							Runnable r = new Runnable () {
								public void run() {
																	
									table.getSelectionModel().removeSelectionInterval(0, files.length);
									table.setRowSelectionInterval(pressedRow, pressedRow);
									table.setColumnSelectionInterval(0, 0);
									table.requestFocusInWindow();
									table.requestFocus();
								}
							};
							
							SwingUtilities.invokeLater(r);
						}
							
						// add the focus to the specified row
						else {
								
							table.getSelectionModel().removeSelectionInterval(0, files.length);
								
							for (int i = 0; i < selectedRows.length; i++) {
								if (i == 0) {
									table.setRowSelectionInterval(selectedRows[i], selectedRows[i]);
								} else {
									table.addRowSelectionInterval(selectedRows[i], selectedRows[i]);
								}
								
								Runnable r = new Runnable () {
									public void run() {
										
										table.addRowSelectionInterval(pressedRow, pressedRow);
										table.setColumnSelectionInterval(0, 0);
										table.requestFocusInWindow();
										table.requestFocus();
										
									}
								};
								
								SwingUtilities.invokeLater(r);	
								
							}							
						}
					}
				}
				
			}

			/* (non-Javadoc)
			 * @see javax.swing.plaf.basic.BasicTableUI$MouseInputHandler#mouseReleased(java.awt.event.MouseEvent)
			 */
			public void mouseReleased(MouseEvent e) {

				if (SwingUtilities.isLeftMouseButton(e)) {
					Point p = e.getPoint();
					final int pressedRow = table.rowAtPoint(p);
					
					if (e.isControlDown()) {
	
						boolean alreadySelected = false;
	
						int[] selectedRows = table.getSelectedRows();
	
						for (int i = 0; i < selectedRows.length; i++) {
							if (selectedRows[i] == pressedRow) {
								alreadySelected = true;
								break;
							}
						}
	
						if (alreadySelected) {
							table.removeRowSelectionInterval(pressedRow, pressedRow);
						} else {
							table.addRowSelectionInterval(pressedRow, pressedRow);
						}
					}
					
					else if (e.isShiftDown()) {
						ListSelectionModel rsm = getSelectionModel(); 
						ListSelectionModel csm = getColumnModel().getSelectionModel();
						int anchorRow = rsm.getAnchorSelectionIndex(); 
						int anchorCol = csm.getAnchorSelectionIndex();
						
						boolean anchorSelected = isCellSelected(anchorRow, anchorCol);
						
						if (anchorSelected) {
							
							// remove the current selection
							table.getSelectionModel().removeSelectionInterval(0, files.length);
							table.setRowSelectionInterval(anchorRow, pressedRow);
							table.setColumnSelectionInterval(0, 0);
							
						} else {
							// remove the current selection
							table.getSelectionModel().removeSelectionInterval(0, files.length);
							table.setRowSelectionInterval(0, pressedRow);
							table.setColumnSelectionInterval(0, 0);
						}
						
					}
					
					// remove the current selection and select the specified row
					else {
						
						
						Runnable r = new Runnable () {
							public void run() {
								
								table.getSelectionModel().removeSelectionInterval(0, files.length);
								table.setRowSelectionInterval(pressedRow, pressedRow);
								table.setColumnSelectionInterval(0, 0);
								table.requestFocusInWindow();
								table.requestFocus();
								
							}
						};
						
						SwingUtilities.invokeLater(r);	
					}
				}
			}
		};

		/* (non-Javadoc)
		 * @see javax.swing.plaf.basic.BasicTableUI#createMouseInputListener()
		 */
		protected MouseInputListener createMouseInputListener() {
			return handler;
		}
	}

	/**
	 * Due to a bug in the JDK this method must be overridden.
	 */
	class DownloadKeyListener extends KeyAdapter {

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.awt.event.KeyAdapter#keyReleased(java.awt.event.KeyEvent)
		 */
		public void keyReleased(KeyEvent e) {
			if (e.getKeyCode() == KeyEvent.VK_C) {
				if (e.isControlDown()) {
					createClipboardContents();
				}
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.awt.datatransfer.ClipboardOwner#lostOwnership(java.awt.datatransfer.Clipboard,
	 *      java.awt.datatransfer.Transferable)
	 */
	public void lostOwnership(Clipboard clipboard, Transferable contents) {
		// do nothing
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -