📄 filetable.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 + -