SearchPanel.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.CardLayout;
import java.awt.event.*;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;
import javax.swing.*;
import javax.swing.Action;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.apache.log4j.Logger;
import org.xnap.XNap;
import org.xnap.action.*;
import org.xnap.action.AbstractToggleReversedPrefAction;
import org.xnap.event.ListEvent;
import org.xnap.event.ListListener;
import org.xnap.gui.action.*;
import org.xnap.gui.shortcut.*;
import org.xnap.gui.component.CloseableTabbedPane;
import org.xnap.gui.menu.AbstractDynamicMenu;
import org.xnap.gui.menu.PeerMenu;
import org.xnap.gui.util.GUIHelper;
import org.xnap.gui.util.IconHelper;
import org.xnap.peer.Peer;
import org.xnap.plugin.news.NewsPanel;
import org.xnap.search.Search;
import org.xnap.search.SearchManager;
import org.xnap.search.SearchManagerListener;
import org.xnap.search.SearchProvider;
import org.xnap.search.SearchResult;
import org.xnap.search.SearchResultActionProvider;
import org.xnap.transfer.DownloadManager;
import org.xnap.transfer.UploadManager;
import org.xnap.util.FileHelper;
import org.xnap.util.Preferences;
/**
* This class provides a search input panel and tabbed pane that contains
* {@link SearchResultPanel SearchResultPanel} objects.
*/
public class SearchPanel extends JPanel
implements ActionProvider, ChangeListener, ListListener, PeerProvider,
PropertyChangeListener, SearchManagerListener {
//--- Constant(s) ---
/**
* File that was used to save the search history.
*/
public static final String HISTORY_FILENAME
= FileHelper.getHomeDir() + "search_history3";
//--- Data field(s) ---
protected static Preferences prefs = Preferences.getInstance();
private JMenu jmPopup;
private SimpleSearchQueryPanel jpSimple;
private AdvancedSearchQueryPanel jpAdvanced;
private CloseableTabbedPane jtpSearches;
private JSplitPane jspH;
private JSplitPane jspV;
private JTabbedPane jtpTransfer;
private StopAction acStop = new StopAction();
private RequeryAction acRequery = new RequeryAction();
private Action acPeerMenu
= new MenuAction(new PeerMenu(this), "users.png");
private Action acShowAdvanced
= new ShowAdvancedSearchOptionsAction();
private Action acShowSimple
= new ShowSimpleSearchOptionsAction();
private CardLayout clCenter;
private JPanel jpCenter;
private NewsPanel newsPanel;
private List actionProviders = new ArrayList();
private static Logger logger = Logger.getLogger(SearchPanel.class);
private JComponent logoPanel;
//--- Constructor(s) ---
/**
* Constructs the search panel.
*/
public SearchPanel()
{
initialize();
SearchManager.getInstance().setListener(this);
// register column menus
// ColumnModel cm = TableColumnsMenu.toModel
// (SearchTableModel.createDefaultColumns());
// JMenu jm = new TableColumnsMenu
// (XNap.tr("Search Table"), cm, Preferences.getInstance(), "search",
// 2);
//XNapFrame.getInstance().getMainMenuBar().addTableColumnsMenu(jm);
// jm = new TableColumnsMenu
// (XNap.tr("Browse Table"), cm, Preferences.getInstance(), "browse",
// 2);
//XNapFrame.getInstance().getMainMenuBar().addTableColumnsMenu(jm);
SearchManager.getInstance().addListListener(this);
prefs.addPropertyChangeListener("showAdvancedSearchOptions", this);
propertyChange(null);
updateActions();
}
//--- Method(s) ---
public void registerActionProvider(SearchResultActionProvider provider)
{
actionProviders.add(provider);
}
public void deregisterActionProvider(SearchResultActionProvider provider)
{
actionProviders.remove(provider);
}
public SearchResultActionProvider[] getActionProviders()
{
return (SearchResultActionProvider[])
actionProviders.toArray(new SearchResultActionProvider[] {});
}
private void initialize()
{
// popup menu
jmPopup = new SearchResultMenu();
DefaultComboBoxModel dcm = readHistoryFile();
// simple search query panel
jpSimple = new SimpleSearchQueryPanel(dcm);
// advanced search query panel
jpAdvanced = new AdvancedSearchQueryPanel(dcm);
//GridBagHelper.add(jpAdvanced, new XNapButton(new ShowSimpleAction()));
// tabbed pane
jtpSearches = new CloseableTabbedPane();
jtpSearches.setBorder(GUIHelper.createLoweredBorder());
jtpSearches.addContainerListener(new TabListener());
jtpSearches.addChangeListener(this);
// center panel
clCenter = new CardLayout();
jpCenter = new JPanel();
jpCenter.setBorder(GUIHelper.createEmptyBorder());
jpCenter.setLayout(clCenter);
jpCenter.add(jtpSearches, "Search");
setLogoPanel(createDefaultLogoPanel());
// transfer panel
jtpTransfer = new JTabbedPane();
jtpTransfer.setBorder(GUIHelper.createLoweredBorder());
// download panel
TransferManagerPanel jpDownloads = new TransferManagerPanel
(DownloadManager.getInstance(), "filteredDownload", true);
jtpTransfer.addTab(XNap.tr("Downloads"),
IconHelper.getTabTitleIcon("down.png"),
jpDownloads);
// upload panel
TransferManagerPanel jpUploads = new TransferManagerPanel
(UploadManager.getInstance(), "filteredUpload", true);
jtpTransfer.addTab(XNap.tr("Uploads"),
IconHelper.getTabTitleIcon("up.png"),
jpUploads);
// split panel
jspV = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
jspV.setDividerLocation(prefs.getSearchDividerLocation());
jspV.setOneTouchExpandable(true);
jspV.setResizeWeight(1);
jspV.setBorder(GUIHelper.createEmptyBorder());
jspV.add(jpCenter, JSplitPane.TOP);
jspV.add(jtpTransfer, JSplitPane.BOTTOM);
jspH = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
jspH.setDividerLocation(prefs.getInt("searchHorizontalDividerLocation"));
jspH.setBorder(GUIHelper.createEmptyBorder());
jspH.setDividerSize(2);
jspH.add(jpAdvanced);
jspH.add(jspV);
setBorder(GUIHelper.createEmptyBorder());
setLayout(new BorderLayout());
add(jpSimple, BorderLayout.NORTH);
add(jspH, BorderLayout.CENTER);
// shortcuts
ShortcutManager.getInstance().add(acRequery, this);
ShortcutManager.getInstance().add(acStop, this);
}
/**
* @return
*/
public static JComponent createDefaultLogoPanel()
{
// logo
JLabel logoPanel = new JLabel(IconHelper.getImage("xnap_logo.png"));
logoPanel.setHorizontalAlignment(SwingConstants.CENTER);
logoPanel.setVerticalAlignment(SwingConstants.CENTER);
return logoPanel;
}
public void handle(Search search)
{
SearchResultPanel ssp = (search.showTree())
? new SearchResultTreePanel(this, search)
: new SearchResultPanel(this, search);
if (search.getFilter() != null) {
jpSimple.addToHistory(search.getFilter());
}
jtpSearches.addTab(ssp.getTitle(), ssp);
}
/**
* Invoked when a {@link SearchProvider} has been added.
*/
public void itemAdded(final ListEvent event)
{
Runnable runner = new Runnable()
{
public void run()
{
jpAdvanced.providerAdded((SearchProvider)event.getItem());
jpSimple.providerAdded((SearchProvider)event.getItem());
}
};
SwingUtilities.invokeLater(runner);
}
/**
* Invoked when a {@link SearchProvider} has been removed.
*/
public void itemRemoved(final ListEvent event)
{
Runnable runner = new Runnable()
{
public void run()
{
jpAdvanced.providerRemoved
((SearchProvider)event.getItem());
jpSimple.providerRemoved
((SearchProvider)event.getItem());
}
};
SwingUtilities.invokeLater(runner);
}
/**
* Returns the advanced search query panel.
*/
public AdvancedSearchQueryPanel getAdvancedPanel()
{
return jpAdvanced;
}
/**
* Returns the transfer panel.
*/
public JTabbedPane getSearchResultPanel()
{
return jtpSearches;
}
/**
* Returns the transfer panel.
*/
public JTabbedPane getTransferPanel()
{
return jtpTransfer;
}
/**
*
*/
public SimpleSearchQueryPanel getSimple()
{
return jpSimple;
}
public Action[] getActions()
{
return new Action[] {
acStop, acRequery, null, acPeerMenu, null,
acShowSimple, acShowAdvanced,
};
}
public JPopupMenu getPopupMenu()
{
return jmPopup.getPopupMenu();
}
public void savePrefs()
{
if (jspH.isVisible()) {
prefs.set("searchHorizontalDividerLocation",
jspH.getDividerLocation());
}
prefs.setSearchDividerLocation(jspV.getDividerLocation());
writeHistoryFile();
}
/**
* Returns the currently selected search result panel.
*
* @return null, if no panel is visible; the panel, otherwise
*/
public SearchResultPanel getSelectedTab()
{
return (SearchResultPanel)jtpSearches.getSelectedComponent();
}
/**
* Called when a tab is selected.
*/
public void stateChanged(ChangeEvent e)
{
updateActions();
}
/**
* Sets the title of <code>tab</code> to <code>title</code>.
*
* @param tab the search result panel
* @param title the title
*/
public void setTabTitle(SearchResultPanel tab, String title)
{
int i = jtpSearches.indexOfComponent(tab);
if (i != -1) {
jtpSearches.setTitleAt(i, title);
}
}
/**
* Returns the currently selected {@link Peer} objects.
*
* @return null, if nothing is selected; the peers, otherwise
*/
public Peer[] getPeers()
{
SearchResultPanel sp = getSelectedTab();
if (sp != null) {
SearchResult results[] = sp.getSelectedResults();
if (results != null) {
LinkedList l = new LinkedList();
for (int i = 0; i < results.length; i++) {
if (results[i].getPeer() != null) {
l.add(results[i].getPeer());
}
}
return (Peer[])l.toArray(new Peer[0]);
}
}
return null;
}
public void propertyChange(PropertyChangeEvent e)
{
if (jpAdvanced.isVisible()) {
prefs.set("searchHorizontalDividerLocation",
jspH.getDividerLocation());
}
jpSimple.setVisible(!prefs.getBoolean("showAdvancedSearchOptions"));
jpAdvanced.setVisible(prefs.getBoolean("showAdvancedSearchOptions"));
if (jpAdvanced.isVisible()) {
int size
= Math.max(prefs.getInt("searchHorizontalDividerLocation"),
(int)jpAdvanced.getMinimumSize().getWidth());
jspH.setDividerLocation(size);
}
}
public void updateActions()
{
SearchResultPanel sp = getSelectedTab();
if (sp != null) {
acStop.setEnabled(!sp.getController().isDone());
acRequery.setEnabled(sp.getController().isDone());
}
else {
acStop.setEnabled(false);
acRequery.setEnabled(false);
}
}
public void setLogoPanel(JComponent panel)
{
if (logoPanel != null) {
jpCenter.remove(logoPanel);
}
logoPanel = (panel != null) ? panel : createDefaultLogoPanel();
jpCenter.add(logoPanel, "Logo");
if (jtpSearches.getComponentCount() == 0) {
clCenter.show(jpCenter, "Logo");
}
}
/**
* Reads history file into a new combobox model.
*/
private DefaultComboBoxModel readHistoryFile()
{
Vector v = new Vector();
try {
FileHelper.readBinary(new File(HISTORY_FILENAME), v);
}
catch (IOException ie) {
logger.debug("Error reading history file" , ie);
}
return new DefaultComboBoxModel(v);
}
/**
* Stores history items.
*/
private void writeHistoryFile()
{
List l = Arrays.asList(jpAdvanced.getHistoryItems());
try {
FileHelper.writeBinary(new File(HISTORY_FILENAME), l);
}
catch (IOException ie) {
logger.debug("Error writing history file", ie);
}
}
/**
* Makes sure the XNap logo is shown once all sub panels are closed.
*/
private class TabListener implements ContainerListener
{
public void componentAdded(ContainerEvent e)
{
updateLayout(e.getID());
}
public void componentRemoved(ContainerEvent e)
{
updateLayout(e.getID());
}
private void updateLayout(int id)
{
if (id == ContainerEvent.COMPONENT_REMOVED
&& jtpSearches.getComponentCount() == 0) {
clCenter.show(jpCenter, "Logo");
}
else {
clCenter.show(jpCenter, "Search");
}
}
}
/**
* Stops the search in the currently focused tab.
*/
private class StopAction extends AbstractAction {
public StopAction()
{
putValue(Action.NAME, XNap.tr("Stop"));
putValue(Action.SHORT_DESCRIPTION, XNap.tr("Stops search."));
putValue(IconHelper.XNAP_ICON, "stop.png");
putValue(AbstractXNapAction.SHORTCUT_CATEGORY, XNap.tr("Search"));
putValue(Action.ACTION_COMMAND_KEY, "stopSearch");
}
public void actionPerformed(ActionEvent event)
{
SearchResultPanel srp = getSelectedTab();
if (srp != null) {
setEnabled(false);
srp.getController().stop();
}
updateActions();
}
}
/**
* Reperforms a search.
*/
private class RequeryAction extends AbstractAction
{
public RequeryAction()
{
putValue(Action.NAME, XNap.tr("Requery"));
putValue(Action.SHORT_DESCRIPTION,
XNap.tr("Perform search again"));
putValue(IconHelper.XNAP_ICON, "reload3.png");
putValue(AbstractXNapAction.DEFAULT_KEYSTROKE,
KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0));
putValue(AbstractXNapAction.SHORTCUT_CATEGORY, XNap.tr("Search"));
putValue(Action.ACTION_COMMAND_KEY, "requerySearch");
}
public void actionPerformed(ActionEvent event)
{
SearchResultPanel srp = getSelectedTab();
if (srp != null) {
jtpSearches.remove(srp);
// FIX: we should requery in the same panel
SearchManager.getInstance().handle
(srp.getController().getSearch());
}
}
}
/**
* Switches between simple and advanced view.
*/
private class ShowAdvancedSearchOptionsAction
extends AbstractTogglePrefAction {
public ShowAdvancedSearchOptionsAction()
{
super("showAdvancedSearchOptions");
putValue(Action.NAME, XNap.tr("Advanced"));
putValue(Action.SHORT_DESCRIPTION,
XNap.tr("Displays advanced search options panel."));
putValue(IconHelper.XNAP_ICON, "view_left_right.png");
}
public void toggled(boolean selected)
{
// handled by propertyChange()
}
}
/**
* Switches between simple and advanced view.
*/
private class ShowSimpleSearchOptionsAction
extends AbstractToggleReversedPrefAction {
public ShowSimpleSearchOptionsAction()
{
super("showAdvancedSearchOptions");
putValue(Action.NAME, XNap.tr("Simple"));
putValue(Action.SHORT_DESCRIPTION,
XNap.tr("Displays simple search options panel."));
putValue(IconHelper.XNAP_ICON, "view_top_bottom.png");
}
public void toggled(boolean selected)
{
// handled by propertyChange()
}
}
/**
* Provides the popup menu.
*/
private class SearchResultMenu extends AbstractDynamicMenu
{
public SearchResultMenu()
{
super(XNap.tr("Results"));
}
/**
* Builds the intersection of all actions of all selected
* search results and adds them to the top of the menu. */
protected void willBecomeVisible()
{
removeAllTemporaries();
SearchResult[] results = getSelectedTab().getSelectedResults();
int count1 = ActionHelper.addCommonActions
(this, results, new SearchResultActionProvider(), 0);
int count2 = PeerMenu.addActions(this, getPeers());
for (int i = 0; i < actionProviders.size(); i++) {
Action[] acts =
((org.xnap.search.SearchResultActionProvider)actionProviders.get(i))
.getActions(results);
if (acts != null) {
for (int j = 0; j < acts.length; j++) {
if (acts[j] != null) {
addTemporary(ActionHelper.createMenuItem(acts[j]));
}
}
}
}
if (count1 > 0 && count2 > 0) {
addTemporary(new JPopupMenu.Separator(), count1);
}
}
private class SearchResultActionProvider
implements ActionHelper.ActionExtractor
{
public Action[] getActions(Object o)
{
return ((SearchResult)o).getActions();
}
}
}
}
The table below shows all metrics for SearchPanel.java.




