package org.limewire.ui.swing.filter;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import org.jdesktop.swingx.JXList;
import org.jdesktop.swingx.decorator.ColorHighlighter;
import org.jdesktop.swingx.decorator.HighlightPredicate;
import org.limewire.ui.swing.components.RolloverCursorListener;
import org.limewire.ui.swing.filter.AbstractFilter.FilterResources;
import org.limewire.ui.swing.util.I18n;
/**
* Display panel for filter popup window. This is used by PropertyFilter to
* display the "more" popup, and SourceFilter to display the "friend" popup.
*/
class FilterPopupPanel extends JPanel {
private static final int MAX_VISIBLE_ROWS = 18;
private final JPanel titlePanel = new JPanel();
private final JLabel titleLabel = new JLabel();
private final JButton closeButton = new JButton();
private final JXList list = new JXList();
private final JScrollPane scrollPane = new JScrollPane();
private final JPopupMenu popupMenu = new JPopupMenu();
private boolean popupReady;
private boolean popupTriggered;
/**
* Constructs a FilterPopupPanel with the specified resources and title
* text.
*/
public FilterPopupPanel(FilterResources resources, String titleText) {
setBorder(BorderFactory.createLineBorder(resources.getPopupBorderColor(), 2));
setLayout(new BorderLayout());
titlePanel.setBackground(resources.getPopupHeaderBackground());
titlePanel.setBorder(BorderFactory.createEmptyBorder(1, 3, 1, 1));
titlePanel.setLayout(new BorderLayout());
titleLabel.setForeground(resources.getPopupHeaderForeground());
titleLabel.setFont(resources.getPopupHeaderFont());
titleLabel.setText(I18n.tr("All {0}", titleText));
closeButton.setBorder(BorderFactory.createEmptyBorder(0, 3, 3, 3));
closeButton.setContentAreaFilled(false);
closeButton.setForeground(resources.getPopupHeaderForeground());
closeButton.setIcon(resources.getPopupCloseIcon());
closeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
hidePopup();
}
});
// Add listener to show cursor on mouse over.
new RolloverCursorListener().install(closeButton);
list.setFont(resources.getRowFont());
list.setForeground(resources.getRowColor());
list.setOpaque(false);
list.setRolloverEnabled(true);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
// Add highlighter for rollover.
list.setHighlighters(new ColorHighlighter(HighlightPredicate.ROLLOVER_ROW,
resources.getHighlightBackground(), resources.getHighlightForeground()));
// Add listener to show cursor on mouse over.
new RolloverCursorListener().install(list);
scrollPane.setBorder(BorderFactory.createEmptyBorder());
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setViewportView(list);
popupMenu.setBorder(BorderFactory.createEmptyBorder());
popupMenu.setFocusable(false);
popupMenu.addPopupMenuListener(new PopupMenuListener() {
@Override
public void popupMenuCanceled(PopupMenuEvent e) {
}
@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
if (popupTriggered) {
popupReady = false;
} else {
popupReady = true;
}
}
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
popupTriggered = true;
}
});
add(titlePanel, BorderLayout.NORTH);
add(scrollPane, BorderLayout.CENTER);
titlePanel.add(titleLabel, BorderLayout.CENTER);
titlePanel.add(closeButton, BorderLayout.EAST);
popupMenu.add(this);
}
/**
* Sets the cell renderer on the list.
*/
public void setListCellRenderer(ListCellRenderer renderer) {
list.setCellRenderer(renderer);
}
/**
* Sets the data model on the list.
*/
public void setListModel(ListModel model) {
list.setModel(model);
}
/**
* Sets the selection model on the list.
*/
public void setListSelectionModel(ListSelectionModel selectionModel) {
list.setSelectionModel(selectionModel);
}
/**
* Returns true if the popup is ready to be displayed. The return
* value will be false if the popup is about to be hidden due to a
* triggering event.
*/
public boolean isPopupReady() {
return popupReady;
}
/**
* Sets an indicator that determines whether the popup is ready to be
* displayed.
*/
public void setPopupReady(boolean popupReady) {
this.popupReady = popupReady;
}
/**
* Sets an indicator that determines whether a triggering event is
* about to occur that affects popup visibility.
*/
public void setPopupTriggered(boolean popupTriggered) {
this.popupTriggered = popupTriggered;
}
/**
* Displays this panel in a popup window at the x,y position relative to
* the specified invoker.
*/
public void showPopup(Component invoker, int x, int y) {
// Adjust popup list height.
list.setVisibleRowCount(Math.min(list.getModel().getSize(), MAX_VISIBLE_ROWS));
// Limit popup width.
if (popupMenu.getPreferredSize().width > 275) {
popupMenu.setPreferredSize(new Dimension(275, popupMenu.getPreferredSize().height));
}
// Display popup next to property label. Coordinates are relative
// to the invoker, so we adjust the horizontal position to align
// with the list, and the vertical position to align with the
// filter label.
popupMenu.show(invoker, x, y);
}
/**
* Hides the popup window.
*/
public void hidePopup() {
popupMenu.setVisible(false);
}
}