package com.limegroup.gnutella.gui.search; import java.awt.Insets; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.CardLayout; import java.awt.Dimension; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.SwingUtilities; import com.limegroup.gnutella.gui.MagnetButton; import com.limegroup.gnutella.settings.UISettings; import com.limegroup.gnutella.gui.themes.ThemeMediator; import com.limegroup.gnutella.gui.themes.ThemeObserver; /** * Manages input for the search, including filters for active searches. */ final class SearchInputManager implements ThemeObserver { /** * The panel that contains all input information for searching. * This includes both 'input boxes' and 'filter boxes'. */ private final JPanel COMPONENT_PANEL = new JPanel(new GridBagLayout()); /** * The card layout switching between searching or filtering. */ private final CardLayout MAIN_CARDS = new CardLayout(); /** * The panel containing either search input or filters. */ private final JPanel MAIN_PANEL = new JPanel(MAIN_CARDS); /** * The search input panel. */ private SearchInputPanel SEARCH; /** * The filter input panel. */ private FilterInputPanel FILTER; /** * Constructs a new search input manager class, including all displayed * elements for search input. */ SearchInputManager() { updateTheme(); ThemeMediator.addThemeObserver(this); } public void updateTheme() { SEARCH = new SearchInputPanel(); FILTER = new FilterInputPanel(new ShowSearchListener(), new AutoSearchListener()); MAIN_PANEL.removeAll(); MAIN_PANEL.add(SEARCH, "search"); MAIN_PANEL.add(FILTER, "filter"); COMPONENT_PANEL.removeAll(); GridBagConstraints c = new GridBagConstraints(); c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.BOTH; c.weightx = 1; c.weighty = 1; c.insets = new Insets(5, 0, 0, 0); COMPONENT_PANEL.add(MAIN_PANEL, c); c.fill = GridBagConstraints.NONE; c.weightx = 0; c.weighty = 0; c.insets = new Insets(0, 0, 0, 0); if(UISettings.MAGNETMIX_BUTTON.getValue() && !isResolutionLow()) COMPONENT_PANEL.add(new MagnetButton(), c); } private boolean isResolutionLow() { Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); return screenSize.width <= 800 || screenSize.height <= 600; } void rebuild() { updateTheme(); } void addressChanged() { SEARCH.addressChanged(); } void goToSearch() { SwingUtilities.invokeLater(new Runnable() { public void run() { showSearchCard(false); } }); } void requestSearchFocus() { requestSearchFocus(false); } /** * Returns the <tt>JComponent</tt> instance containing the UI elements * for the search input section of the search tab. * * @return the <tt>JComponent</tt> instance containing the UI elements * for the search input section of the search tab */ JComponent getComponent() { return COMPONENT_PANEL; } /** * Removes all filters from the list of filters. */ void clearFilters() { FILTER.clearFilters(); showSearchCard(false); } /** * Resets the FilterPanel for the specified ResultPanel. */ void panelReset(ResultPanel rp) { FILTER.panelReset(rp); } /** * Removes the filter associated with the specified result panel. */ void panelRemoved(ResultPanel rp) { if(FILTER.panelRemoved(rp)) showSearchCard(false); } /** * Creates and/or displays filters for the specified result panel. */ void setFiltersFor(ResultPanel rp) { if(UISettings.SEARCH_RESULT_FILTERS.getValue()) { boolean added = FILTER.setFiltersFor(rp); MAIN_CARDS.last(MAIN_PANEL); if(added) requestFilterFocus(); } } /** * Displays the search card. */ private void showSearchCard(boolean immediate) { MAIN_CARDS.first(MAIN_PANEL); requestSearchFocus(immediate); } /** * Requests focus for the search field. */ private void requestSearchFocus(boolean immediate) { if(immediate) SEARCH.requestSearchFocusImmediately(); else SEARCH.requestSearchFocus(); } /** * Requests focus on the correct area of the filter. */ private void requestFilterFocus() { FILTER.requestFilterFocus(); } /** * Listener for switching back to the search from a filter. */ private class ShowSearchListener implements ActionListener { public void actionPerformed(ActionEvent e) { goToSearch(); } } /** * Listener for key events. */ private class AutoSearchListener implements KeyListener { public void keyPressed(KeyEvent e) { forward(e); } public void keyReleased(KeyEvent e) { forward(e); } public void keyTyped(KeyEvent e) { if(forward(e)) { SwingUtilities.invokeLater(new Runnable() { public void run() { showSearchCard(true); } }); } } /** * Forwards a key event to the search field. */ private boolean forward(KeyEvent e) { if(SEARCH.isKeyEventForwardable()) { SEARCH.getForwardingSearchField().processKeyEvent(e); return true; } else { return false; } } } }