/* * #%L * org.gitools.ui.app * %% * Copyright (C) 2013 - 2014 Universitat Pompeu Fabra - Biomedical Genomics group * %% * 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, either version 3 of the * License, or (at your option) any later version. * * 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, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ package org.gitools.ui.app.actions; import org.apache.commons.lang.ArrayUtils; import org.gitools.api.components.IEditor; import org.gitools.heatmap.Bookmark; import org.gitools.heatmap.Bookmarks; import org.gitools.heatmap.Heatmap; import org.gitools.ui.app.dialog.BookmarkEditPage; import org.gitools.ui.app.heatmap.editor.HeatmapEditor; import org.gitools.ui.core.Application; import org.gitools.ui.core.actions.HeatmapAction; import org.gitools.ui.core.actions.IPanelAction; import org.gitools.ui.platform.IconUtils; import org.gitools.ui.platform.icons.IconNames; import org.gitools.ui.platform.wizard.PageDialog; import javax.swing.*; import javax.swing.event.ListDataEvent; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Vector; //FIXME: always two listeners. public class BookmarksDropdown extends HeatmapAction implements IPanelAction, PropertyChangeListener { private WideComboBox<Bookmark> bookmarkComboBox; private JPanel bookmarksSelectPanel; private Bookmarks bookmarks; private static Bookmark NO_OPTION = new Bookmark(); public BookmarksDropdown() { super("Bookmarks dropdown"); bookmarksSelectPanel.setVisible(false); bookmarkComboBox.setRenderer(new BookmarkCellRenderer()); bookmarkComboBox.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { bookmarkComboBox.getModel().setSelectedItem(NO_OPTION); } }); } @Override protected boolean isEnabledByEditor(IEditor editor) { if (!(editor instanceof HeatmapEditor)) { bookmarksSelectPanel.setVisible(false); bookmarksSelectPanel.repaint(); return false; } else { return isEnabledByModel(editor.getModel()); } } @Override public boolean isEnabledByModel(Object model) { if (model instanceof Heatmap) { Bookmarks b = ((Heatmap) model).getBookmarks(); b.addPropertyChangeListener(Bookmarks.PROPERTY_CONTENTS, this); setBookmarks(b); bookmarksSelectPanel.repaint(); return true; } bookmarksSelectPanel.setVisible(false); bookmarksSelectPanel.repaint(); return false; } private void setBookmarks(final Bookmarks bookmarks) { this.bookmarks = bookmarks; Bookmark[] bookmarkArray = bookmarks.getAll().toArray(new Bookmark[bookmarks.getAll().size()]); bookmarksSelectPanel.setVisible(bookmarks.getAll().size() > 0); if (bookmarks.getAll().size() == 0) return; NO_OPTION.setName(String.valueOf(bookmarkArray.length) + (bookmarkArray.length > 1 ? " Bookmarks:" : " Bookmark:")); bookmarkArray = (Bookmark[]) ArrayUtils.add(bookmarkArray, 0, NO_OPTION); bookmarkComboBox.setModel(new DefaultComboBoxModel<>(bookmarkArray)); bookmarkComboBox.getModel().setSelectedItem(NO_OPTION); } @Override public JPanel getPanel() { bookmarksSelectPanel.setOpaque(false); return bookmarksSelectPanel; } @Override public void actionPerformed(ActionEvent e) { // Nothing } @Override public void propertyChange(PropertyChangeEvent evt) { if (!bookmarks.equals(evt.getNewValue())) { bookmarks.removePropertyChangeListener(this); } setBookmarks(getHeatmap().getBookmarks()); bookmarkComboBox.contentsChanged(new ListDataEvent(evt, 0, 0, 0)); bookmarksSelectPanel.revalidate(); bookmarksSelectPanel.repaint(); } class BookmarkCellRenderer extends DefaultListCellRenderer { Icon icon; JPanel panel; JButton btn; Bookmark bookmark; //so we will install the mouse listener once boolean isFirst = true; BookmarkCellRenderer() { super(); panel = new JPanel(new BorderLayout()); icon = IconUtils.getIconResource(IconNames.edit16); btn = new JButton(icon); btn.setPreferredSize(new Dimension(icon.getIconWidth(), icon.getIconHeight())); panel.add(btn, BorderLayout.WEST); panel.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { e.consume(); if (!bookmark.equals(NO_OPTION) && clickOnButon(e.getX())) { BookmarkEditPage page = new BookmarkEditPage(getHeatmap(), bookmark, false); PageDialog dialog = new PageDialog(Application.get(), page); dialog.open(); if (dialog.isCancelled()) { return; } if (page.isDelete()) { bookmarks.removeBookmark(page.getBookmark()); Application.get().showNotification("Bookmark " + bookmark.getName() + " removed."); } else { bookmarks.removeBookmark(bookmark); bookmarks.add(page.getBookmark()); } } else { if (!bookmark.equals(NO_OPTION)) { getHeatmap().applyBookmark(bookmark); Application.get().showNotificationPermanent("Bookmark " + bookmark.getName() + " applied."); } } } }); } private boolean clickOnButon(int x) { return btn.getX() + btn.getWidth() > x; } @Override public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) { if (isSelected) { bookmark = (Bookmark) value; } Component comp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); if (value != null && value.equals(NO_OPTION) && bookmarkComboBox.isPopupVisible()) { setForeground(Color.LIGHT_GRAY); } if (value != null && !value.equals(NO_OPTION)) { panel.add(comp); if (isFirst) { isFirst = false; list.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { panel.dispatchEvent(e); e.consume(); } }); } return panel; } return comp; } } public static class WideComboBox<E> extends JComboBox<E> { public WideComboBox() { } public WideComboBox(final E items[]) { super(items); } public WideComboBox(Vector items) { super(items); } public WideComboBox(ComboBoxModel aModel) { super(aModel); } private boolean layingOut = false; public void doLayout() { try { layingOut = true; super.doLayout(); } finally { layingOut = false; } } public Dimension getSize() { Dimension dim = super.getSize(); if (!layingOut) dim.width = Math.max(dim.width, getPreferredSize().width); return dim; } } }