Coverage Report - org.dishevelled.venn.cytoscape.GroupsView
 
Classes in this File Line Coverage Branch Coverage Complexity
GroupsView
0%
0/198
0%
0/22
2
GroupsView$1
0%
0/4
0%
0/2
2
GroupsView$2
0%
0/9
0%
0/4
2
GroupsView$3
0%
0/9
0%
0/4
2
GroupsView$4
0%
0/3
N/A
2
GroupsView$5
0%
0/6
0%
0/10
2
GroupsView$6
0%
0/7
0%
0/2
2
GroupsView$7
0%
0/1
N/A
2
 
 1  
 /*
 2  
 
 3  
     dsh-venn-cytoscape-plugin  Cytoscape plugin for venn diagrams.
 4  
     Copyright (c) 2010-2012 held jointly by the individual authors.
 5  
 
 6  
     This library is free software; you can redistribute it and/or modify it
 7  
     under the terms of the GNU Lesser General Public License as published
 8  
     by the Free Software Foundation; either version 3 of the License, or (at
 9  
     your option) any later version.
 10  
 
 11  
     This library is distributed in the hope that it will be useful, but WITHOUT
 12  
     ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
 13  
     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 14  
     License for more details.
 15  
 
 16  
     You should have received a copy of the GNU Lesser General Public License
 17  
     along with this library;  if not, write to the Free Software Foundation,
 18  
     Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA.
 19  
 
 20  
     > http://www.fsf.org/licensing/licenses/lgpl.html
 21  
     > http://www.opensource.org/licenses/lgpl-license.php
 22  
 
 23  
 */
 24  
 package org.dishevelled.venn.cytoscape;
 25  
 
 26  
 import static javax.swing.SwingUtilities.windowForComponent;
 27  
 import static org.dishevelled.venn.cytoscape.VennDiagramsUtils.installCloseKeyBinding;
 28  
 import static org.dishevelled.venn.cytoscape.VennDiagramsUtils.nameOf;
 29  
 
 30  
 import java.awt.BorderLayout;
 31  
 import java.awt.Toolkit;
 32  
 
 33  
 import java.awt.event.ActionEvent;
 34  
 import java.awt.event.InputEvent;
 35  
 import java.awt.event.KeyEvent;
 36  
 
 37  
 import java.awt.geom.Rectangle2D;
 38  
 
 39  
 import java.util.ArrayList;
 40  
 import java.util.HashSet;
 41  
 import java.util.List;
 42  
 import java.util.Set;
 43  
 
 44  
 import javax.swing.AbstractAction;
 45  
 import javax.swing.Action;
 46  
 import javax.swing.InputMap;
 47  
 import javax.swing.KeyStroke;
 48  
 import javax.swing.JCheckBoxMenuItem;
 49  
 import javax.swing.JComponent;
 50  
 import javax.swing.JDialog;
 51  
 import javax.swing.JList;
 52  
 import javax.swing.JPanel;
 53  
 import javax.swing.JPopupMenu;
 54  
 import javax.swing.JScrollPane;
 55  
 import javax.swing.SwingUtilities;
 56  
 
 57  
 import javax.swing.border.EmptyBorder;
 58  
 
 59  
 import javax.swing.event.ListSelectionEvent;
 60  
 import javax.swing.event.ListSelectionListener;
 61  
 
 62  
 import ca.odell.glazedlists.EventList;
 63  
 import ca.odell.glazedlists.GlazedLists;
 64  
 
 65  
 import ca.odell.glazedlists.swing.EventListModel;
 66  
 import ca.odell.glazedlists.swing.EventSelectionModel;
 67  
 
 68  
 import com.google.common.base.Joiner;
 69  
 
 70  
 import cytoscape.CyNode;
 71  
 
 72  
 import cytoscape.groups.CyGroup;
 73  
 import cytoscape.groups.CyGroupChangeListener;
 74  
 import cytoscape.groups.CyGroupManager;
 75  
 import cytoscape.groups.CyGroupViewer;
 76  
 
 77  
 import cytoscape.view.CyNetworkView;
 78  
 
 79  
 import org.dishevelled.iconbundle.IconBundle;
 80  
 import org.dishevelled.iconbundle.IconSize;
 81  
 
 82  
 import org.dishevelled.iconbundle.impl.CachingIconBundle;
 83  
 import org.dishevelled.iconbundle.impl.PNGIconBundle;
 84  
 
 85  
 import org.dishevelled.identify.ContextMenuListener;
 86  
 import org.dishevelled.identify.IdentifiableAction;
 87  
 import org.dishevelled.identify.IdButton;
 88  
 import org.dishevelled.identify.IdMenuItem;
 89  
 import org.dishevelled.identify.IdToolBar;
 90  
 
 91  
 import org.dishevelled.layout.ButtonPanel;
 92  
 import org.dishevelled.layout.LabelFieldPanel;
 93  
 
 94  
 import org.dishevelled.piccolo.venn.BinaryVennNode;
 95  
 import org.dishevelled.piccolo.venn.TernaryVennNode;
 96  
 import org.dishevelled.piccolo.venn.QuaternaryVennNode;
 97  
 import org.dishevelled.piccolo.venn.VennNode;
 98  
 
 99  
 import org.dishevelled.venn.VennModel;
 100  
 import org.dishevelled.venn.VennLayout;
 101  
 import org.dishevelled.venn.VennLayouter;
 102  
 import org.dishevelled.venn.VennLayouter.PerformanceHint;
 103  
 
 104  
 import org.dishevelled.venn.cytoscape.CyGroupListCellRenderer;
 105  
 import org.dishevelled.venn.model.VennModels;
 106  
 
 107  
 import org.dishevelled.venn.swing.BinaryVennList;
 108  
 import org.dishevelled.venn.swing.TernaryVennList;
 109  
 import org.dishevelled.venn.swing.QuaternaryVennList;
 110  
 
 111  
 import org.cytoscape.venneuler.VennEulerLayouter;
 112  
 
 113  
 /**
 114  
  * Groups view.
 115  
  */
 116  0
 final class GroupsView
 117  
     extends JPanel
 118  
     implements CyGroupChangeListener, CyGroupViewer
 119  
 {
 120  
     /** List of groups. */
 121  
     private final EventList<CyGroup> groups;
 122  
 
 123  
     /** List selection. */
 124  
     private final EventList<CyGroup> selected;
 125  
 
 126  
     /** List of groups. */
 127  
     private final JList groupList;
 128  
 
 129  
     /** Context menu. */
 130  
     private final JPopupMenu contextMenu;
 131  
 
 132  
     /** Euler diagram action icon bundle. */
 133  0
     private final IconBundle eulerDiagramIconBundle = new CachingIconBundle(new PNGIconBundle("/org/dishevelled/venn/cytoscape/eulerDiagram"));
 134  
 
 135  
     /** Euler diagram action. */
 136  0
     private final IdentifiableAction eulerDiagram = new IdentifiableAction("Euler Diagram...", eulerDiagramIconBundle) // i18n
 137  0
         {
 138  
             /** {@inheritDoc} */
 139  
             public void actionPerformed(final ActionEvent event)
 140  
             {
 141  0
                 if (selected.size() > 1)
 142  
                 {
 143  0
                     eulerDiagram();
 144  
                 }
 145  0
             }
 146  
         };
 147  
 
 148  
     /** Venn diagram action icon bundle. */
 149  0
     private final IconBundle vennDiagramIconBundle = new CachingIconBundle(new PNGIconBundle("/org/dishevelled/venn/cytoscape/vennDiagram"));
 150  
 
 151  
     /** Venn diagram action. */
 152  0
     private final IdentifiableAction vennDiagram = new IdentifiableAction("Venn Diagram...", vennDiagramIconBundle) // i18n
 153  0
         {
 154  
             /** {@inheritDoc} */
 155  
             public void actionPerformed(final ActionEvent event)
 156  
             {
 157  0
                 switch (selected.size())
 158  
                 {
 159  
                     case 2:
 160  0
                         binaryDiagram();
 161  0
                         break;
 162  
                     case 3:
 163  0
                         ternaryDiagram();
 164  0
                         break;
 165  
                     case 4:
 166  0
                         quaternaryDiagram();
 167  0
                         break;
 168  
                     default:
 169  
                         break;
 170  
                 }
 171  0
             }
 172  
         };
 173  
 
 174  
     /** Details action icon bundle. */
 175  0
     private final IconBundle detailsIconBundle = new CachingIconBundle(new PNGIconBundle("/org/dishevelled/venn/cytoscape/details"));
 176  
 
 177  
     /** Details action. */
 178  0
     private final IdentifiableAction details = new IdentifiableAction("Details...", detailsIconBundle) // i18n
 179  0
         {
 180  
             /** {@inheritDoc} */
 181  
             public void actionPerformed(final ActionEvent event)
 182  
             {
 183  0
                 switch (selected.size())
 184  
                 {
 185  
                     case 2:
 186  0
                         binaryDetails();
 187  0
                         break;
 188  
                     case 3:
 189  0
                         ternaryDetails();
 190  0
                         break;
 191  
                     case 4:
 192  0
                         quaternaryDetails();
 193  0
                         break;
 194  
                     default:
 195  
                         break;
 196  
                 }
 197  0
             }
 198  
         };
 199  
 
 200  
     /** Done action. */
 201  0
     private final Action done = new AbstractAction("Done") // i18n
 202  0
         {
 203  
             /** {@inheritDoc} */
 204  
             public void actionPerformed(final ActionEvent event)
 205  
             {
 206  0
                 done();
 207  0
             }
 208  
         };
 209  
 
 210  
     /** List selection listener. */
 211  0
     private final ListSelectionListener listSelectionListener = new ListSelectionListener()
 212  0
         {
 213  
             /** {@inheritDoc} */
 214  
             public void valueChanged(final ListSelectionEvent event)
 215  
             {
 216  0
                 int size = selected.size();
 217  0
                 eulerDiagram.setEnabled(size > 1);
 218  0
                 vennDiagram.setEnabled(size > 1 && size < 5);
 219  0
                 details.setEnabled(size > 1 && size < 5);
 220  0
             }
 221  
         };
 222  
 
 223  
     /** Venn euler layouter. */
 224  0
     private final VennLayouter<CyNode> vennLayouter = new VennEulerLayouter<CyNode>();
 225  
 
 226  
 
 227  
     /**
 228  
      * Create a new groups view.
 229  
      */
 230  
     GroupsView()
 231  
     {
 232  0
         super();
 233  
 
 234  0
         groups = GlazedLists.eventList(CyGroupManager.getGroupList());
 235  0
         EventListModel<CyGroup> listModel = new EventListModel<CyGroup>(groups);
 236  0
         EventSelectionModel<CyGroup> selectionModel = new EventSelectionModel<CyGroup>(groups);
 237  0
         selected = selectionModel.getSelected();
 238  0
         selectionModel.addListSelectionListener(listSelectionListener); // or use event list listener
 239  0
         groupList = new JList(listModel);
 240  0
         groupList.setSelectionModel(selectionModel);
 241  0
         groupList.setCellRenderer(new CyGroupListCellRenderer());
 242  
 
 243  0
         InputMap inputMap = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
 244  0
         int menuKeyMask = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
 245  0
         KeyStroke ctrlShiftE = KeyStroke.getKeyStroke(KeyEvent.VK_E, menuKeyMask | InputEvent.SHIFT_DOWN_MASK);
 246  0
         KeyStroke ctrlShiftV = KeyStroke.getKeyStroke(KeyEvent.VK_V, menuKeyMask | InputEvent.SHIFT_DOWN_MASK);
 247  0
         KeyStroke ctrlShiftD = KeyStroke.getKeyStroke(KeyEvent.VK_D, menuKeyMask | InputEvent.SHIFT_DOWN_MASK);
 248  0
         inputMap.put(ctrlShiftE, "eulerDiagram");
 249  0
         inputMap.put(ctrlShiftV, "vennDiagram");
 250  0
         inputMap.put(ctrlShiftD, "details");
 251  0
         getActionMap().put("eulerDiagram", eulerDiagram);
 252  0
         getActionMap().put("vennDiagram", vennDiagram);
 253  0
         getActionMap().put("details", details);
 254  
 
 255  0
         IdMenuItem eulerDiagramMenuItem = new IdMenuItem(eulerDiagram);
 256  0
         eulerDiagramMenuItem.setAccelerator(ctrlShiftE);
 257  0
         IdMenuItem vennDiagramMenuItem = new IdMenuItem(vennDiagram);
 258  0
         vennDiagramMenuItem.setAccelerator(ctrlShiftV);
 259  0
         IdMenuItem detailsMenuItem = new IdMenuItem(details);
 260  0
         detailsMenuItem.setAccelerator(ctrlShiftD);
 261  
 
 262  0
         contextMenu = new JPopupMenu();
 263  0
         contextMenu.add(eulerDiagramMenuItem);
 264  0
         contextMenu.add(vennDiagramMenuItem);
 265  0
         contextMenu.add(detailsMenuItem);
 266  0
         groupList.addMouseListener(new ContextMenuListener(contextMenu));
 267  
 
 268  0
         eulerDiagram.setEnabled(false);
 269  0
         vennDiagram.setEnabled(false);
 270  0
         details.setEnabled(false);
 271  
 
 272  0
         layoutComponents();
 273  0
         CyGroupManager.registerGroupViewer(this);
 274  0
         CyGroupManager.addGroupChangeListener(this);
 275  0
     }
 276  
 
 277  
     /**
 278  
      * Layout components.
 279  
      */
 280  
     private void layoutComponents()
 281  
     {
 282  0
         LabelFieldPanel mainPanel = new LabelFieldPanel();
 283  0
         mainPanel.setBorder(new EmptyBorder(12, 12, 0, 12));
 284  0
         mainPanel.addLabel("Groups:"); // i18n
 285  0
         mainPanel.addFinalField(new JScrollPane(groupList));
 286  
 
 287  0
         IdToolBar toolBar = new IdToolBar();
 288  0
         IdButton eulerDiagramButton = toolBar.add(eulerDiagram);
 289  0
         eulerDiagramButton.setBorderPainted(false);
 290  0
         eulerDiagramButton.setFocusPainted(false);
 291  0
         IdButton vennDiagramButton = toolBar.add(vennDiagram);
 292  0
         vennDiagramButton.setBorderPainted(false);
 293  0
         vennDiagramButton.setFocusPainted(false);
 294  0
         IdButton detailsButton = toolBar.add(details);
 295  0
         detailsButton.setBorderPainted(false);
 296  0
         detailsButton.setFocusPainted(false);
 297  
 
 298  0
         toolBar.displayIcons();
 299  0
         toolBar.setIconSize(IconSize.DEFAULT_24X24);
 300  
 
 301  0
         JPopupMenu toolBarContextMenu = new JPopupMenu();
 302  0
         for (Object menuItem : toolBar.getDisplayMenuItems())
 303  
         {
 304  0
             toolBarContextMenu.add((JCheckBoxMenuItem) menuItem);
 305  
         }
 306  0
         toolBar.addMouseListener(new ContextMenuListener(toolBarContextMenu));
 307  
 
 308  0
         ButtonPanel buttonPanel = new ButtonPanel();
 309  0
         buttonPanel.setBorder(new EmptyBorder(24, 12, 12, 12));
 310  0
         buttonPanel.add(done);
 311  
 
 312  0
         setLayout(new BorderLayout());
 313  0
         add("North", toolBar);
 314  0
         add("Center", mainPanel);
 315  0
         add("South", buttonPanel);
 316  0
     }
 317  
 
 318  
     /**
 319  
      * Done.
 320  
      */
 321  
     private void done()
 322  
     {
 323  0
         windowForComponent(this).setVisible(false);
 324  
         // todo:  unregister listeners and dispose?
 325  0
     }
 326  
 
 327  
     /**
 328  
      * Show a euler diagram.
 329  
      */
 330  
     private void eulerDiagram()
 331  
     {
 332  0
         List<String> labels = new ArrayList<String>(selected.size());
 333  0
         List<Set<CyNode>> sets = new ArrayList<Set<CyNode>>(selected.size());
 334  0
         for (CyGroup selectedGroup : selected)
 335  
         {
 336  0
             labels.add(nameOf(selectedGroup));
 337  0
             sets.add(new HashSet<CyNode>(selectedGroup.getNodes()));
 338  
         }
 339  0
         final VennModel<CyNode> model = VennModels.createVennModel(sets);
 340  0
         final VennNode<CyNode> vennNode = new VennNode<CyNode>(model);
 341  
         // add ctr that takes List<String> labels as parameter?
 342  0
         for (int i = 0, size = labels.size(); i < size; i++)
 343  
         {
 344  0
             vennNode.setLabelText(i, labels.get(i));
 345  
         }
 346  
 
 347  0
         JDialog dialog = new JDialog(windowForComponent(this), Joiner.on(", ").join(labels) + " Euler Diagram");
 348  0
         dialog.setContentPane(new DiagramView(vennNode));
 349  0
         dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
 350  0
         installCloseKeyBinding(dialog);
 351  
 
 352  
         // todo: offset per parent dialog
 353  0
         dialog.setBounds(100, 100, 600, 600);
 354  0
         if (model.size() > 4) {
 355  0
             dialog.setBounds(100, 100, 800, 800);
 356  
         }
 357  0
         dialog.setVisible(true);
 358  
 
 359  
         // run in a cytoscape task?
 360  0
         SwingUtilities.invokeLater(new Runnable()
 361  0
             {
 362  
                 /** {@inheritDoc} */
 363  
                 public void run()
 364  
                 {
 365  0
                     Rectangle2D.Double boundingRectangle = new Rectangle2D.Double(0.0d, 0.0d, 400.0d, 400.0d);
 366  0
                     if (model.size() > 4) {
 367  0
                         boundingRectangle.setRect(0.0d, 0.0d, 600.0d, 600.0d);
 368  
                     }
 369  0
                     VennLayout layout = vennLayouter.layout(model, boundingRectangle, PerformanceHint.OPTIMIZE_FOR_SPEED);
 370  0
                     vennNode.setLayout(layout);
 371  0
                 }
 372  
             });
 373  0
     }
 374  
 
 375  
     /**
 376  
      * Show a binary venn diagram.
 377  
      */
 378  
     private void binaryDiagram()
 379  
     {
 380  0
         String firstLabel = selected.get(0).getGroupName();
 381  0
         String secondLabel = selected.get(1).getGroupName();
 382  0
         Set<CyNode> first = new HashSet<CyNode>(selected.get(0).getNodes());
 383  0
         Set<CyNode> second = new HashSet<CyNode>(selected.get(1).getNodes());
 384  0
         BinaryVennNode<CyNode> binaryVennNode = new BinaryVennNode<CyNode>(firstLabel, first, secondLabel, second);
 385  
 
 386  0
         JDialog dialog = new JDialog(windowForComponent(this), firstLabel + ", " + secondLabel + " Venn Diagram");
 387  0
         dialog.setContentPane(new DiagramView(binaryVennNode));
 388  0
         dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
 389  0
         installCloseKeyBinding(dialog);
 390  
 
 391  
         // todo: offset per parent dialog
 392  0
         dialog.setBounds(100, 100, 400, 400);
 393  0
         dialog.setVisible(true);
 394  0
     }
 395  
 
 396  
     /**
 397  
      * Show a ternary venn diagram.
 398  
      */
 399  
     private void ternaryDiagram()
 400  
     {
 401  0
         String firstLabel = selected.get(0).getGroupName();
 402  0
         String secondLabel = selected.get(1).getGroupName();
 403  0
         String thirdLabel = selected.get(2).getGroupName();
 404  0
         Set<CyNode> first = new HashSet<CyNode>(selected.get(0).getNodes());
 405  0
         Set<CyNode> second = new HashSet<CyNode>(selected.get(1).getNodes());
 406  0
         Set<CyNode> third = new HashSet<CyNode>(selected.get(2).getNodes());
 407  0
         TernaryVennNode<CyNode> ternaryVennNode = new TernaryVennNode<CyNode>(firstLabel, first, secondLabel, second, thirdLabel, third);
 408  
 
 409  0
         JDialog dialog = new JDialog(windowForComponent(this), firstLabel + ", " + secondLabel + ", " + thirdLabel + " Venn Diagram");
 410  0
         dialog.setContentPane(new DiagramView(ternaryVennNode));
 411  0
         dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
 412  0
         installCloseKeyBinding(dialog);
 413  
 
 414  
         // todo: offset per parent dialog
 415  0
         dialog.setBounds(100, 100, 400, 400);
 416  0
         dialog.setVisible(true);
 417  0
     }
 418  
 
 419  
     /**
 420  
      * Show a quaternary venn diagram.
 421  
      */
 422  
     private void quaternaryDiagram()
 423  
     {
 424  0
         String firstLabel = selected.get(0).getGroupName();
 425  0
         String secondLabel = selected.get(1).getGroupName();
 426  0
         String thirdLabel = selected.get(2).getGroupName();
 427  0
         String fourthLabel = selected.get(3).getGroupName();
 428  0
         Set<CyNode> first = new HashSet<CyNode>(selected.get(0).getNodes());
 429  0
         Set<CyNode> second = new HashSet<CyNode>(selected.get(1).getNodes());
 430  0
         Set<CyNode> third = new HashSet<CyNode>(selected.get(2).getNodes());
 431  0
         Set<CyNode> fourth = new HashSet<CyNode>(selected.get(3).getNodes());
 432  0
         QuaternaryVennNode<CyNode> quaternaryVennNode = new QuaternaryVennNode<CyNode>(firstLabel, first, secondLabel, second, thirdLabel, third, fourthLabel, fourth);
 433  
 
 434  0
         JDialog dialog = new JDialog(windowForComponent(this), firstLabel + ", " + secondLabel + ", " + thirdLabel + ", " + fourthLabel + " Venn Diagram");
 435  0
         dialog.setContentPane(new DiagramView(quaternaryVennNode));
 436  0
         dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
 437  0
         installCloseKeyBinding(dialog);
 438  
 
 439  
         // todo: offset per parent dialog
 440  0
         dialog.setBounds(100, 100, 600, 600);
 441  0
         dialog.setVisible(true);
 442  0
     }
 443  
 
 444  
     /**
 445  
      * Show binary venn details.
 446  
      */
 447  
     private void binaryDetails()
 448  
     {
 449  0
         String firstLabel = selected.get(0).getGroupName();
 450  0
         String secondLabel = selected.get(1).getGroupName();
 451  0
         Set<CyNode> first = new HashSet<CyNode>(selected.get(0).getNodes());
 452  0
         Set<CyNode> second = new HashSet<CyNode>(selected.get(1).getNodes());
 453  0
         final BinaryVennList<CyNode> binaryVennList = new BinaryVennList<CyNode>(firstLabel, first, secondLabel, second);
 454  
 
 455  0
         JDialog dialog = new JDialog(windowForComponent(this), firstLabel + ", " + secondLabel + " Details");
 456  0
         dialog.setContentPane(new DetailsView(binaryVennList));
 457  0
         dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
 458  0
         installCloseKeyBinding(dialog);
 459  
 
 460  
         // todo: offset per parent dialog
 461  0
         dialog.setBounds(100, 100, 600, 450);
 462  0
         dialog.setVisible(true);
 463  0
     }
 464  
 
 465  
     /**
 466  
      * Show ternary venn details.
 467  
      */
 468  
     private void ternaryDetails()
 469  
     {
 470  0
         String firstLabel = selected.get(0).getGroupName();
 471  0
         String secondLabel = selected.get(1).getGroupName();
 472  0
         String thirdLabel = selected.get(2).getGroupName();
 473  0
         Set<CyNode> first = new HashSet<CyNode>(selected.get(0).getNodes());
 474  0
         Set<CyNode> second = new HashSet<CyNode>(selected.get(1).getNodes());
 475  0
         Set<CyNode> third = new HashSet<CyNode>(selected.get(2).getNodes());
 476  0
         final TernaryVennList<CyNode> ternaryVennList = new TernaryVennList<CyNode>(firstLabel, first, secondLabel, second, thirdLabel, third);
 477  
 
 478  0
         JDialog dialog = new JDialog(windowForComponent(this), firstLabel + ", " + secondLabel + ", " + thirdLabel + " Details");
 479  0
         dialog.setContentPane(new DetailsView(ternaryVennList));
 480  0
         dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
 481  0
         installCloseKeyBinding(dialog);
 482  
 
 483  
         // todo: offset per parent dialog
 484  0
         dialog.setBounds(100, 100, 747, 669);
 485  0
         dialog.setVisible(true);
 486  0
     }
 487  
 
 488  
     /**
 489  
      * Show quaternary venn details.
 490  
      */
 491  
     private void quaternaryDetails()
 492  
     {
 493  0
         String firstLabel = selected.get(0).getGroupName();
 494  0
         String secondLabel = selected.get(1).getGroupName();
 495  0
         String thirdLabel = selected.get(2).getGroupName();
 496  0
         String fourthLabel = selected.get(3).getGroupName();
 497  0
         Set<CyNode> first = new HashSet<CyNode>(selected.get(0).getNodes());
 498  0
         Set<CyNode> second = new HashSet<CyNode>(selected.get(1).getNodes());
 499  0
         Set<CyNode> third = new HashSet<CyNode>(selected.get(2).getNodes());
 500  0
         Set<CyNode> fourth = new HashSet<CyNode>(selected.get(3).getNodes());
 501  0
         final QuaternaryVennList<CyNode> quaternaryVennList = new QuaternaryVennList<CyNode>(firstLabel, first, secondLabel, second, thirdLabel, third, fourthLabel, fourth);
 502  
 
 503  0
         JDialog dialog = new JDialog(windowForComponent(this), firstLabel + ", " + secondLabel + ", " + thirdLabel + ", " + fourthLabel + " Details");
 504  0
         dialog.setContentPane(new DetailsView(quaternaryVennList));
 505  0
         dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
 506  0
         installCloseKeyBinding(dialog);
 507  
 
 508  
         // todo: offset per parent dialog
 509  0
         dialog.setBounds(100, 100, 894, 888);
 510  0
         dialog.setVisible(true);
 511  0
     }
 512  
 
 513  
     /** {@inheritDoc} */
 514  
     public String getViewerName()
 515  
     {
 516  0
         return "Venn/Euler Diagrams";
 517  
     }
 518  
 
 519  
     /** {@inheritDoc} */
 520  
     public void groupChanged(final CyGroup group, final CyNode changedNode, CyGroupViewer.ChangeType change)
 521  
     {
 522  
         // ignore for now
 523  0
     }
 524  
 
 525  
     /** {@inheritDoc} */
 526  
     public void groupCreated(final CyGroup group)
 527  
     {
 528  0
         if (!groups.contains(group))
 529  
         {
 530  0
             groups.add(group);
 531  
         }
 532  0
     }
 533  
 
 534  
     /** {@inheritDoc} */
 535  
     public void groupCreated(final CyGroup group, final CyNetworkView networkView)
 536  
     {
 537  0
         if (!groups.contains(group))
 538  
         {
 539  0
             groups.add(group);
 540  
         }
 541  0
     }
 542  
 
 543  
     /** {@inheritDoc} */
 544  
     public void groupWillBeRemoved(final CyGroup group)
 545  
     {
 546  0
         if (groups.contains(group))
 547  
         {
 548  0
             groups.remove(group);
 549  
         }
 550  0
     }
 551  
 
 552  
     /** {@inheritDoc} */
 553  
     public void groupChanged(final CyGroup group, final CyGroupChangeListener.ChangeType change)
 554  
     {
 555  0
         switch (change)
 556  
         {
 557  
             case GROUP_CREATED:
 558  0
                 if (!groups.contains(group))
 559  
                 {
 560  0
                     groups.add(group);
 561  
                 }
 562  
                 break;
 563  
             case GROUP_DELETED:
 564  0
                 if (groups.contains(group))
 565  
                 {
 566  0
                     groups.remove(group);
 567  
                 }
 568  
                 break;
 569  
             case GROUP_MODIFIED:
 570  
             default:
 571  
                 break;
 572  
         }
 573  0
     }
 574  
 }