/* Copyright 2008-2010 Gephi Authors : Mathieu Bastian <mathieu.bastian@gephi.org> Website : http://www.gephi.org This file is part of Gephi. Gephi is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Gephi 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Gephi. If not, see <http://www.gnu.org/licenses/>. */ package org.gephi.ui.filters.plugin.partition; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.text.NumberFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.swing.BorderFactory; import javax.swing.DefaultListCellRenderer; import javax.swing.DefaultListModel; import javax.swing.Icon; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.ListCellRenderer; import javax.swing.SwingUtilities; import javax.swing.plaf.basic.BasicListUI; import org.gephi.filters.plugin.partition.PartitionBuilder.PartitionFilter; import org.gephi.partition.api.Part; import org.gephi.partition.api.Partition; import org.openide.util.NbBundle; /** * * @author Mathieu Bastian */ public class PartitionPanel extends javax.swing.JPanel { private PartitionFilter filter; private JPopupMenu popupMenu; public PartitionPanel() { initComponents(); setMinimumSize(new Dimension(50, 90)); //List renderer final ListCellRenderer renderer = new DefaultListCellRenderer() { @Override public Component getListCellRendererComponent(final JList list, final Object value, final int index, final boolean isSelected, final boolean cellHasFocus) { final JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); PartWrapper pw = (PartWrapper) value; if (pw.isEnabled()) { label.setEnabled(true); label.setIcon(pw.icon); } else { label.setEnabled(false); label.setDisabledIcon(pw.disabledIcon); } label.setFont(label.getFont().deriveFont(10f)); label.setIconTextGap(6); setOpaque(false); setForeground(list.getForeground()); setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); return label; } }; list.setCellRenderer(renderer); //List click MouseListener mouseListener = new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (SwingUtilities.isLeftMouseButton(e)) { int index = list.locationToIndex(e.getPoint()); if (index == -1) { return; } PartWrapper pw = (PartWrapper) list.getModel().getElementAt(index); boolean set = !pw.isEnabled(); pw.setEnabled(set); if (set) { filter.addPart(pw.getPart()); } else { filter.removePart(pw.getPart()); } list.repaint(); } } @Override public void mousePressed(MouseEvent e) { if (filter != null) { if (e.isPopupTrigger()) { popupMenu.show(e.getComponent(), e.getX(), e.getY()); } } } @Override public void mouseReleased(MouseEvent e) { if (e.isPopupTrigger()) { popupMenu.show(e.getComponent(), e.getX(), e.getY()); } } }; list.addMouseListener(mouseListener); //Popup createPopup(); } public void setup(final PartitionFilter filter) { this.filter = filter; final Partition partition = filter.getCurrentPartition(); if (partition != null) { refresh(partition, filter.getParts()); } } private void refresh(Partition partition, List<Part> currentParts) { final DefaultListModel model = new DefaultListModel(); Set<Part> filterParts = new HashSet<Part>(currentParts); Part[] parts = partition.getParts(); Arrays.sort(parts); for (int i = 0; i < parts.length; i++) { final Part p = parts[parts.length - 1 - i]; PartWrapper pw = new PartWrapper(p, p.getColor()); pw.setEnabled(filterParts.contains(p)); model.add(i, pw); } list.setModel(model); } private static class PartWrapper { private final Part part; private final PaletteIcon icon; private final PaletteIcon disabledIcon; private boolean enabled = false; private static final NumberFormat formatter = NumberFormat.getPercentInstance(); public PartWrapper(Part part, Color color) { this.part = part; this.icon = new PaletteIcon(color); this.disabledIcon = new PaletteIcon(); formatter.setMaximumFractionDigits(2); } public PaletteIcon getIcon() { return icon; } public Part getPart() { return part; } @Override public String toString() { String percentage = formatter.format(part.getPercentage()); return part.getDisplayName() + " (" + percentage + ")"; } public boolean isEnabled() { return enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } } private void createPopup() { popupMenu = new JPopupMenu(); JMenuItem refreshItem = new JMenuItem(NbBundle.getMessage(PartitionPanel.class, "PartitionPanel.action.refresh")); refreshItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { setup(filter); } }); popupMenu.add(refreshItem); JMenuItem selectItem = new JMenuItem(NbBundle.getMessage(PartitionPanel.class, "PartitionPanel.action.selectall")); selectItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { filter.selectAll(); refresh(filter.getCurrentPartition(), Arrays.asList(filter.getCurrentPartition().getParts())); } }); popupMenu.add(selectItem); JMenuItem unselectItem = new JMenuItem(NbBundle.getMessage(PartitionPanel.class, "PartitionPanel.action.unselectall")); unselectItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { filter.unselectAll(); refresh(filter.getCurrentPartition(), new ArrayList<Part>()); } }); popupMenu.add(unselectItem); } public static void computeListSize(final JList list) { if (list.getUI() instanceof BasicListUI) { final BasicListUI ui = (BasicListUI) list.getUI(); try { final Method method = BasicListUI.class.getDeclaredMethod("updateLayoutState"); method.setAccessible(true); method.invoke(ui); list.revalidate(); list.repaint(); } catch (final SecurityException e) { e.printStackTrace(); } catch (final NoSuchMethodException e) { e.printStackTrace(); } catch (final IllegalArgumentException e) { e.printStackTrace(); } catch (final IllegalAccessException e) { e.printStackTrace(); } catch (final InvocationTargetException e) { e.printStackTrace(); } } } private static class PaletteIcon implements Icon { private final int COLOR_WIDTH; private final int COLOR_HEIGHT; private final Color BORDER_COLOR; private final Color color; public PaletteIcon(Color color) { this.color = color; BORDER_COLOR = new Color(0x444444); COLOR_WIDTH = 11; COLOR_HEIGHT = 11; } public PaletteIcon() { this.color = new Color(0xDDDDDD); BORDER_COLOR = new Color(0x999999); COLOR_WIDTH = 11; COLOR_HEIGHT = 11; } public int getIconWidth() { return COLOR_WIDTH; } public int getIconHeight() { return COLOR_HEIGHT + 2; } public void paintIcon(Component c, Graphics g, int x, int y) { g.setColor(BORDER_COLOR); g.drawRect(x + 2, y, COLOR_WIDTH, COLOR_HEIGHT); g.setColor(color); g.fillRect(x + 2 + 1, y + 1, COLOR_WIDTH - 1, COLOR_HEIGHT - 1); } } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { jScrollPane1 = new javax.swing.JScrollPane(); list = new javax.swing.JList(); setLayout(new java.awt.BorderLayout()); jScrollPane1.setBorder(null); jScrollPane1.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); list.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); list.setOpaque(false); jScrollPane1.setViewportView(list); add(jScrollPane1, java.awt.BorderLayout.CENTER); }// </editor-fold>//GEN-END:initComponents // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JScrollPane jScrollPane1; private javax.swing.JList list; // End of variables declaration//GEN-END:variables }