/* * This file is part of muCommander, http://www.mucommander.com * Copyright (C) 2002-2016 Maxence Bernard * * muCommander 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; either version 3 of the License, or * (at your option) any later version. * * muCommander 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, see <http://www.gnu.org/licenses/>. */ package com.mucommander.ui.quicklist; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Insets; import java.awt.Point; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.util.Vector; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.border.LineBorder; import com.mucommander.ui.quicklist.item.QuickListHeaderItem; /** * This abstract class contains some common features to all file table's popups: * 1. add HeaderMenuItem as the first item. * 2. set custom line border. * 3. does the calculations needed in order to show the popup in the center of the * invoker FolderPanel. * * @author Arik Hadas */ public abstract class QuickList extends JPopupMenu implements FocusListener { private static final int PADDING = 2; protected QuickListHeaderItem headerMenuItem; private java.util.List<Component> items = new Vector<Component>(); private QuickListContainer container; protected QuickList(QuickListContainer container, String header) { super(); this.container = container; setBorder(new PopupsBorder()); add(headerMenuItem = new QuickListHeaderItem(header)); setFocusTraversalKeysEnabled(false); } protected Component nextFocusableComponent() { return container.nextFocusableComponent(); } /** * This function is called before showing quick-list. * If the return value is true, the quick list will be shown. Otherwise, it won't be shown. */ protected abstract boolean prepareForShowing(QuickListContainer container); public void show() { if (prepareForShowing(container)) { // Note: the actual popup menu's size is not known at this stage so we use the component's preferred size Dimension dim = getPreferredSize(); Point location = container.calcQuickListPosition(dim); show(container.containerComponent(), location.x, location.y); getFocus(); } } @Override public Component add(Component comp) { items.add(comp); return super.add(comp); } @Override public JMenuItem add(JMenuItem comp) { items.add(comp); return super.add(comp); } @Override public Dimension getPreferredSize() { double width = PADDING, height = PADDING; for (Component item : items) { width = Math.max(width, item.getPreferredSize().getWidth()); height += item.getPreferredSize().getHeight(); } return new Dimension((int) Math.ceil( Math.max(container == null ? 0 : container.getWidth() / 2, width * 1.05)) , (int) Math.ceil(height)); } public void focusGained(FocusEvent arg0) {} public void focusLost(FocusEvent arg0) { setVisible(false); } /** * Get focus for the desired subcomponent. Only subclasses know which * component to focus, so they must implement it. */ protected abstract void getFocus(); public static class PopupsBorder extends LineBorder { public PopupsBorder() { super(Color.gray); } @Override public Insets getBorderInsets(Component c) { return new Insets(1,1,1,1); } @Override public Insets getBorderInsets(Component c, Insets i) { return new Insets(1,1,1,1); } } }