LibraryPanel.java
| Index Score | ||
|---|---|---|
![]() |
![]() |
org.xnap.gui |
![]() |
![]() |
XNap 3 |
View: Reasons, Metrics, Source Code
These are the metrics that contribute to the Enerjy Score for this file, ranked by impact. So the metrics listed at the top influence the score to a greater extent that the metrics listed at the bottom.
/*
* XNap - A P2P framework and client.
*
* See the file AUTHORS for copyright information.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.xnap.gui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Vector;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import org.apache.log4j.Logger;
import org.xnap.XNap;
import org.xnap.action.AbstractTogglePrefAction;
import org.xnap.action.AbstractXNapAction;
import org.xnap.gui.action.CopyFileAction;
import org.xnap.gui.action.CutFileAction;
import org.xnap.gui.action.EnqueueFileAction;
import org.xnap.gui.action.EraseAction;
import org.xnap.gui.action.OpenFileAction;
import org.xnap.gui.action.PasteFileAction;
import org.xnap.gui.action.PlayFileAction;
import org.xnap.gui.action.StopPlayerAction;
import org.xnap.gui.component.FileCompletionModel;
import org.xnap.gui.component.HistoryComboBox;
import org.xnap.gui.component.XNapButton;
import org.xnap.gui.component.XNapMenuItem;
import org.xnap.gui.component.XNapTextField;
import org.xnap.gui.event.DoubleClickListener;
import org.xnap.gui.event.PopupListener;
import org.xnap.gui.menu.OpenFileWithMenu;
import org.xnap.gui.menu.ViewerMenu;
import org.xnap.gui.shortcut.ShortcutManager;
import org.xnap.gui.table.LibraryTableModel;
import org.xnap.gui.tree.LibraryTree;
import org.xnap.gui.util.DragFilesSupport;
import org.xnap.gui.util.FocusHandler;
import org.xnap.gui.util.GUIHelper;
import org.xnap.gui.util.IconHelper;
import org.xnap.gui.util.SwingSynchronizedTask;
import org.xnap.gui.viewer.Viewer;
import org.xnap.gui.viewer.ViewerFrontend;
import org.xnap.gui.viewer.ViewerManager;
import org.xnap.io.Library;
import org.xnap.util.FileHelper;
import org.xnap.util.Formatter;
import org.xnap.util.Preferences;
import org.xnap.util.Scheduler;
public class LibraryPanel extends JPanel
implements ActionProvider, TreeSelectionListener, ListSelectionListener,
DirectoryProvider, FileProvider, ViewerFrontend
{
//--- Constant(s) ---
public static final String HISTORY_FILENAME
= FileHelper.getHomeDir() + "repository_search_history";
//--- Data field(s) ---
private Preferences prefs = Preferences.getInstance();
private LibraryTree lTree;
private JTable jta;
private JFileChooser jfc = null;
private LibraryTableModel ltm;
private DragFilesSupport dfs;
private JSplitPane jspH;
private JSplitPane jspV;
private JPanel jpURL;
private XNapTextField jtfURL;
private JPanel jpSearch;
private HistoryComboBox jcSearch;
// preview
private JPanel jpPreview;
private JScrollPane jspPreview;
private JLabel jlStatus;
private PlayFileAction playAction = new PlayFileAction(this);
private RefreshAction refreshAction = new RefreshAction();
private StopPlayerAction stopAction = new StopPlayerAction();
private EnqueueFileAction enqueueAction = new EnqueueFileAction(this);
private OpenFileAction acOpenFile = new OpenFileAction(this);
private DeleteAction deleteAction = new DeleteAction();
private RenameAction renameAction = new RenameAction();
private CopyFileAction acCopyFile = new CopyFileAction(this);
private CutFileAction acCutFile = new CutFileAction(this);
private PasteFileAction acPasteFile = new PasteFileAction(this);
private ShowURLAction acShowURL = new ShowURLAction();
private ShowSearchAction acShowSearch = new ShowSearchAction();
private File currentDir;
private boolean delayNextViewer;
private Viewer currentViewer;
private static Logger logger = Logger.getLogger(LibraryPanel.class);
//--- Constructor(s) ---
public LibraryPanel()
{
initialize();
}
//--- Method(s) ---
private void initialize()
{
// url panel
Box bxURL = new Box(BoxLayout.X_AXIS);
jtfURL = new XNapTextField(20);
jtfURL.setCompletionModel(new FileCompletionModel());
jtfURL.setPreferences("libraryURL");
Action acEraseURL = new EraseAction(jtfURL);
JButton jbEraseURL = new JButton(acEraseURL);
jbEraseURL.setAlignmentY(0.5f);
jbEraseURL.setMargin(new Insets(1, 1, 1, 1));
bxURL.add(jbEraseURL);
bxURL.add(new JLabel(XNap.tr("Location", 1)));
//Action acQueryURL = new QueryURLAction();
//GUIHelper.bindEnterKey(jtfURL, acQueryURL);
bxURL.add(jtfURL);
jpURL = new JPanel(new BorderLayout());
jpURL.setVisible(prefs.getBoolean("showURLInLibraryPanel"));
jpURL.setBorder(new EmptyBorder(2, 2, 2, 2));
jpURL.add(bxURL, BorderLayout.CENTER);
acShowURL.setPanel(jpURL);
// search panel
Box bxSearch = new Box(BoxLayout.X_AXIS);
Action acQuery = new QueryAction();
EraseAction acErase = new EraseAction();
ShortcutManager.getInstance().add(acErase, this);
JButton jbErase = new JButton(acErase);
jbErase.setMargin(new Insets(1, 1, 1, 1));
jbErase.setAlignmentY(0.5f);
bxSearch.add(jbErase);
JLabel searchLabel = new JLabel(XNap.tr("Library Search", 1));
bxSearch.add(searchLabel);
jcSearch = new HistoryComboBox(readHistoryFile(), 20);
searchLabel.setLabelFor(jcSearch.getTextField());
jcSearch.setPreferences("libararySearch");
GUIHelper.bindEnterKeyLocally(jcSearch.getTextField(), acQuery);
bxSearch.add(jcSearch);
acErase.setTextField(jcSearch.getTextField());
XNapButton jbQuery = new XNapButton(acQuery);
bxSearch.add(jbQuery);
jpSearch = new JPanel(new BorderLayout());
jpSearch.setVisible(prefs.getBoolean("showSearchInLibraryPanel"));
//jpSearch.setBorder(GUIHelper.createDefaultBorder(XNap.tr("Library Search")));
jpSearch.setBorder(new EmptyBorder(2, 2, 2, 2));
jpSearch.add(bxSearch, BorderLayout.CENTER);
acShowSearch.setPanel(jpSearch);
// top
Box bxTop = new Box(BoxLayout.Y_AXIS);
bxTop.add(jpURL);
bxTop.add(jpSearch);
// tree
lTree = new LibraryTree(this);
lTree.addTreeSelectionListener(this);
JScrollPane jspTree = new JScrollPane();
jspTree.setViewportView(lTree);
// table context menu
JPopupMenu popup = new JPopupMenu();
popup.add(new XNapMenuItem(playAction));
popup.add(new XNapMenuItem(enqueueAction));
popup.addSeparator();
popup.add(new XNapMenuItem(acOpenFile));
popup.add(new OpenFileWithMenu(this));
popup.addSeparator();
popup.add(new ViewerMenu(this, this));
popup.addSeparator();
popup.add(new XNapMenuItem(acCopyFile));
popup.add(new XNapMenuItem(acCutFile));
popup.add(new XNapMenuItem(acPasteFile));
popup.addSeparator();
popup.add(new XNapMenuItem(renameAction));
popup.add(new XNapMenuItem(deleteAction));
// table
ltm = new LibraryTableModel();
jta = ltm.createTable(Preferences.getInstance(), "library");
dfs = new DragFilesSupport(jta, this);
jta.getSelectionModel().addListSelectionListener(this);
jta.setShowGrid(false);
jta.addKeyListener(new ArrowKeyListener());
jta.addMouseListener(new PopupListener(popup));
DoubleClickListener.install(jta, acOpenFile);
GUIHelper.bindEmacsKeysToTable(jta);
// new shortcuts stuff
ShortcutManager.getInstance().add(renameAction, jta);
ShortcutManager.getInstance().add(deleteAction, jta);
ShortcutManager.getInstance().add(refreshAction, this);
ShortcutManager.getInstance().add(enqueueAction, jta);
ShortcutManager.getInstance().add(playAction, jta);
ShortcutManager.getInstance().add(acOpenFile, jta);
// jta.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),
// acOpenFile);
// jta.getActionMap().put(acOpenFile, acOpenFile);
// jta.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_Q, 0),
// enqueueAction);
// jta.getActionMap().put(enqueueAction, enqueueAction);
JScrollPane jspTable = new JScrollPane();
jspTable.setViewportView(jta);
// preview panel
jpPreview = new JPanel(new BorderLayout());
jpPreview.setBackground(Color.gray);
jspPreview = new JScrollPane(jpPreview);
ActionListener al = jspPreview.getActionForKeyStroke
(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, 0));
jspPreview.registerKeyboardAction
(al, KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, KeyEvent.CTRL_MASK),
WHEN_IN_FOCUSED_WINDOW);
al = jspPreview.getActionForKeyStroke
(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, 0));
jspPreview.registerKeyboardAction
(al, KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, KeyEvent.CTRL_MASK
| KeyEvent.SHIFT_MASK),
WHEN_IN_FOCUSED_WINDOW);
JScrollBar jsb = jspPreview.getVerticalScrollBar();
jsb.setToolTipText(GUIHelper.tt(XNap.tr("Ctrl+Space to scroll down<br>Ctrl+Shift+Space to scroll up")));
// split panels
jspV = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
jspV.add(jspTable, JSplitPane.TOP);
jspV.add(jspPreview, JSplitPane.BOTTOM);
jspV.setDividerLocation(prefs.getLibraryVerticalDividerLocation());
jspV.setOneTouchExpandable(true);
jspV.setBorder(GUIHelper.createEmptyBorder());
jlStatus = new JLabel(" ");
JPanel jpV = new JPanel(new BorderLayout());
jpV.add(jspV, "Center");
jpV.add(jlStatus, "South");
jspH = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
jspH.add(jspTree, JSplitPane.LEFT);
jspH.add(jpV, JSplitPane.RIGHT);
jspH.setDividerLocation(prefs.getLibraryHorizontalDividerLocation());
jspH.setOneTouchExpandable(true);
jspH.setBorder(GUIHelper.createEmptyBorder());
// focus listener
addComponentListener(new FocusHandler(jcSearch.getTextField()));
// content
setLayout(new BorderLayout());
add(bxTop, BorderLayout.NORTH);
add(jspH, BorderLayout.CENTER);
GUIHelper.setMnemonics(this);
}
private void initializeShortcuts()
{
ShortcutManager sm = ShortcutManager.getInstance();
}
public Action[] getActions()
{
return new Action[] { playAction, enqueueAction, stopAction, null,
refreshAction, null,
acShowURL, acShowSearch, };
}
public void savePrefs()
{
prefs.setLibraryHorizontalDividerLocation(jspH.getDividerLocation());
prefs.setLibraryVerticalDividerLocation(jspV.getDividerLocation());
writeHistoryFile();
}
private void writeHistoryFile()
{
List l = Arrays.asList(jcSearch.getHistoryItems());
try {
FileHelper.writeBinary(new File(HISTORY_FILENAME), l);
}
catch (IOException ie) {
logger.debug("Error writing history file", ie);
}
}
private Vector readHistoryFile()
{
Vector v = new Vector();
try {
FileHelper.readBinary(new File(HISTORY_FILENAME), v);
}
catch (IOException ie) {
logger.debug("Error reading history file" , ie);
}
return v;
}
private void showDirectory(File f)
{
jtfURL.setText(f.getAbsolutePath());
currentDir = f;
ltm.clear();
// check if directory is readable by xnap user
if (f.canRead()) {
ltm.add(f);
ltm.resort();
}
resetPanel();
}
private void showFiles(File[] files)
{
ltm.clear();
ltm.add(files);
ltm.resort();
resetPanel();
}
/**
* Called when a directory has been selected.
*/
public void valueChanged(TreeSelectionEvent e)
{
Object target = e.getPath().getLastPathComponent();
if (target instanceof File) {
File f = (File)target;
showDirectory(f);
}
else {
jtfURL.setText(null);
}
}
/**
* Called when the table's selection changes, we check what kind of
* file was selected and call the respective viewer plugin if available.
*/
public void valueChanged(ListSelectionEvent e)
{
/* user is about to select some files, don't show anything */
if (jta.getSelectedRowCount() > 1) {
resetPanel();
return;
}
int row = jta.getSelectedRow();
if (row != -1) {
if (delayNextViewer) {
delayNextViewer = false;
Scheduler.run(500, new DelayedViewerTask(row));
}
else {
display(ltm.get(row));
}
}
}
/**
* Implements the {@link DirectoryProvider} interface delegating the
* request to the {@link LibraryTree}.
*/
public File getDirectory()
{
return lTree.getDirectory();
}
/**
* Implements the {@link DirectoryProvider#hasChanged}.
*/
public void hasChanged(File directory)
{
if (currentDir != null) {
showDirectory(currentDir);
}
}
private File[] getFiles(boolean showMessage)
{
int rowC = jta.getSelectedRowCount();
int rows[] = jta.getSelectedRows();
if (showMessage && rowC == 0) {
StatusBar.setText(XNap.tr("Please select something first"));
return null;
}
File[] files = new File[rowC];
for (int i = 0; i < rowC; i++) {
files[i] = ltm.get(rows[i]);
}
return files;
}
/**
* Implements {@link FileProvider}.
*/
public File[] getFiles()
{
return getFiles(true);
}
private void display(File file)
{
jtfURL.setText(file.getAbsolutePath());
if (currentViewer != null) {
currentViewer.close();
}
Viewer v = ViewerManager.getInstance().getDefaultViewer(file);
if (v != null && file.canRead()) {
display(v, file);
}
else {
if (v != null) {
StatusBar.setText
(XNap.tr("You do not have permission to read file"));
}
jspPreview.setViewportView(jpPreview);
}
}
/**
* Implements the {@link ViewerFrontend} interface.
*/
public void display(Viewer viewer, File file)
{
jspPreview.setViewportView(viewer.getComponent());
currentViewer = viewer;
viewer.open(file);
}
private void resetPanel()
{
jspPreview.setViewportView(jpPreview);
updateStatus();
}
/**
* Needed for properties serialization.
*/
public int getHorizontalDividerLocation()
{
return jspH.getDividerLocation();
}
/**
* Needed for properties deserialization.
*/
public void setHorizontalDividerLocation(int newValue)
{
if (newValue == -1) {
jspH.setDividerLocation(200);
}
else {
jspH.setDividerLocation(newValue);
}
}
/**
* Needed for properties serialization.
*/
public int getVerticalDividerLocation()
{
return jspV.getDividerLocation();
}
/**
* Needed for properties deserialization.
*/
public void setVerticalDividerLocation(int newValue)
{
if (newValue == -1) {
jspV.setDividerLocation(200);
}
else {
jspV.setDividerLocation(newValue);
}
}
/**
* Updates the status line below the file table.
*/
private void updateStatus()
{
StringBuffer sb = new StringBuffer();
File[] files = getFiles(false);
if (files.length == 0) {
// nothing is selected
sb.append(ltm.getRowCount());
sb.append(" files - ");
sb.append(Formatter.formatSize(ltm.getTotalSize()));
}
else if (files.length == 1) {
sb.append("1 file - ");
sb.append(Formatter.formatNumber(files[0].length()) + " bytes");
}
else {
long totalSize = 0;
for (int i = 0; i < files.length; i++) {
totalSize += files[i].length();
}
sb.append("selected - ");
sb.append(files.length);
sb.append(" files - ");
sb.append(Formatter.formatSize(totalSize));
}
// FIX: we need some kind of padding
sb.insert(0, " ");
jlStatus.setText(sb.toString());
}
/* inner classes */
/**
* Refresh file and directory listings
*/
private class RefreshAction extends AbstractAction
{
public RefreshAction()
{
putValue(Action.NAME, XNap.tr("Refresh"));
putValue(Action.SHORT_DESCRIPTION,
XNap.tr("Refresh list of files"));
putValue(IconHelper.XNAP_ICON, "reload.png");
putValue(Action.ACTION_COMMAND_KEY, "libraryRefresh");
putValue(AbstractXNapAction.DEFAULT_KEYSTROKE,
KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0));
putValue(AbstractXNapAction.SHORTCUT_CATEGORY,
XNap.tr("Library"));
}
public void actionPerformed(ActionEvent event)
{
if (currentDir != null) {
showDirectory(currentDir);
}
}
}
private class DeleteAction extends AbstractAction
{
public DeleteAction()
{
putValue(Action.NAME, XNap.tr("Delete"));
putValue(Action.SHORT_DESCRIPTION,
XNap.tr("Deletes selected file(s)."));
putValue(IconHelper.XNAP_ICON, "editdelete.png");
putValue(Action.ACTION_COMMAND_KEY, "libraryFileDelete");
putValue(AbstractXNapAction.DEFAULT_KEYSTROKE,
KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
putValue(AbstractXNapAction.SHORTCUT_CATEGORY,
XNap.tr("Library"));
}
public void actionPerformed(ActionEvent event)
{
File[] files = getFiles();
if (files == null)
return;
files = Dialogs.showDeleteFilesDialog(LibraryPanel.this, files);
if (files != null) {
for (int i = 0; i < files.length; i++) {
if (!ltm.delete(files[i])) {
StatusBar.setText(XNap.tr("Could not delete {0}",
files[i].getName()));
}
}
}
}
}
private class RenameAction extends AbstractAction
{
public RenameAction()
{
putValue(Action.NAME, XNap.tr("Rename"));
putValue(Action.SHORT_DESCRIPTION,
XNap.tr("Renames the selected file."));
putValue(Action.ACTION_COMMAND_KEY, "libraryFileRename");
putValue(AbstractXNapAction.DEFAULT_KEYSTROKE,
KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0));
putValue(AbstractXNapAction.SHORTCUT_CATEGORY,
XNap.tr("Library"));
}
public void actionPerformed(ActionEvent event)
{
int i = jta.getSelectedRow();
if (i != -1) {
ltm.setCellEditable(i, LibraryTableModel.NAME);
jta.editCellAt(i, LibraryTableModel.NAME);
DefaultCellEditor dce = (DefaultCellEditor)jta.getCellEditor();
JTextField jtf = (JTextField)dce.getComponent();
// jtf.setSelectionStart(0);
// jtf.setSelectionEnd(jtf.getText().length());
jtf.grabFocus();
jtf.setCaretPosition(0);
ltm.setCellEditable(-1, -1);
}
}
}
private class ShowSearchAction extends AbstractTogglePrefAction
{
private JPanel jp;
public ShowSearchAction()
{
super("showSearchInLibraryPanel");
putValue(Action.NAME, XNap.tr("Show Search Input"));
putValue(IconHelper.XNAP_ICON, "filefind.png");
putValue(Action.SHORT_DESCRIPTION,
XNap.tr("Shows or hides the search field."));
}
public void setPanel(JPanel jp)
{
this.jp = jp;
}
public void toggled(boolean visible)
{
if (jp != null) {
jp.setVisible(visible);
}
}
}
private class ShowURLAction extends AbstractTogglePrefAction
{
private JPanel jp;
public ShowURLAction()
{
super("showURLInLibraryPanel");
putValue(Action.NAME, XNap.tr("Show URL Input"));
putValue(IconHelper.XNAP_ICON, "editclear.png");
putValue(Action.SHORT_DESCRIPTION,
XNap.tr("Shows or hides the URL field."));
}
public void setPanel(JPanel jp)
{
this.jp = jp;
}
public void toggled(boolean visible)
{
if (jp != null) {
jp.setVisible(visible);
}
}
}
/**
* Performs a search.
*/
private class QueryAction extends AbstractAction
{
public QueryAction()
{
putValue(Action.NAME, XNap.tr("Query"));
putValue(IconHelper.XNAP_ICON, "filefind.png");
putValue(Action.SHORT_DESCRIPTION, XNap.tr("Performs search."));
}
public void actionPerformed(ActionEvent event)
{
String s = jcSearch.getText().trim();
if (s.length() > 0) {
File[] files = Library.getInstance().search(s);
if (files != null && files.length > 0) {
lTree.clearSelection();
showFiles(files);
StatusBar.setText(XNap.tr("Found {0} files",
new Integer(files.length)));
}
else {
StatusBar.setText(XNap.tr("{0} not found in library", s));
}
jcSearch.addDistinctItemAtTop(s);
}
else {
StatusBar.setText(XNap.tr("What are you trying to search for?"));
}
}
}
private class DelayedViewerTask extends SwingSynchronizedTask
{
private int showRow;
public DelayedViewerTask(int showRow)
{
this.showRow = showRow;
}
public void runSynchronized()
{
if (jta.getSelectedRowCount() == 1
&& jta.getSelectedRow() == showRow) {
display(ltm.get(showRow));
}
}
}
private class ArrowKeyListener extends KeyAdapter {
public void keyPressed(KeyEvent e)
{
int c = e.getKeyCode();
if (c == KeyEvent.VK_PAGE_DOWN || c == KeyEvent.VK_PAGE_UP
|| c == KeyEvent.VK_DOWN || c == KeyEvent.VK_UP) {
delayNextViewer = true;
}
}
}
}
The table below shows all metrics for LibraryPanel.java.




