/* 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.desktop.partition; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Arrays; import java.util.Comparator; import javax.swing.DefaultComboBoxModel; import javax.swing.JPanel; import javax.swing.SwingUtilities; import javax.swing.UIManager; import org.gephi.partition.api.Partition; import org.gephi.partition.api.PartitionController; import org.gephi.partition.api.PartitionModel; import org.gephi.partition.spi.Transformer; import org.gephi.partition.spi.TransformerUI; import org.gephi.ui.utils.BusyUtils; import org.gephi.ui.utils.BusyUtils.BusyLabel; import org.jdesktop.swingx.JXBusyLabel; import org.gephi.ui.utils.UIUtils; import org.openide.util.Lookup; import org.openide.util.NbBundle; /** * * @author Mathieu Bastian */ public class PartitionChooser extends javax.swing.JPanel implements PropertyChangeListener { //Const private final String NO_SELECTION; private final String BUSY_MSG; private final String GROUP_LABEL; private final String UNGROUP_LABEL; private final String SHOW_PIE; private final String HIDE_PIE; //Architecture private PartitionModel model; public PartitionChooser() { initComponents(); initEvents(); if (UIUtils.isAquaLookAndFeel()) { setBackground(UIManager.getColor("NbExplorerView.background")); } NO_SELECTION = NbBundle.getMessage(PartitionChooser.class, "PartitionChooser.choose.text"); BUSY_MSG = NbBundle.getMessage(PartitionChooser.class, "PartitionChooser.busyMessage"); GROUP_LABEL = NbBundle.getMessage(PartitionChooser.class, "PartitionChooser.group.label"); UNGROUP_LABEL = NbBundle.getMessage(PartitionChooser.class, "PartitionChooser.ungroup.label"); SHOW_PIE = NbBundle.getMessage(PartitionChooser.class, "PartitionChooser.showpie.label"); HIDE_PIE = NbBundle.getMessage(PartitionChooser.class, "PartitionChooser.hidepie.label"); refreshModel(); } /** 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() { java.awt.GridBagConstraints gridBagConstraints; chooserPanel = new javax.swing.JPanel(); partitionComboBox = new javax.swing.JComboBox(); refreshToolbar = new javax.swing.JToolBar(); refreshBusyLabel = new JXBusyLabel(new Dimension(18,18)); refreshButton = new javax.swing.JButton(); controlPanel = new javax.swing.JPanel(); applyButton = new javax.swing.JButton(); groupLink = new org.jdesktop.swingx.JXHyperlink(); pieLink = new org.jdesktop.swingx.JXHyperlink(); centerScrollPane = new javax.swing.JScrollPane(); setLayout(new java.awt.BorderLayout()); chooserPanel.setOpaque(false); chooserPanel.setLayout(new java.awt.GridBagLayout()); partitionComboBox.setPreferredSize(new java.awt.Dimension(56, 25)); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 0; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.weightx = 1.0; gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5); chooserPanel.add(partitionComboBox, gridBagConstraints); refreshToolbar.setFloatable(false); refreshToolbar.setRollover(true); refreshToolbar.setOpaque(false); refreshBusyLabel.setText(org.openide.util.NbBundle.getMessage(PartitionChooser.class, "PartitionChooser.refreshBusyLabel.text")); // NOI18N refreshBusyLabel.setVisible(false); refreshToolbar.add(refreshBusyLabel); refreshButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/gephi/desktop/partition/resources/refresh.png"))); // NOI18N refreshButton.setText(org.openide.util.NbBundle.getMessage(PartitionChooser.class, "PartitionChooser.refreshButton.text")); // NOI18N refreshButton.setToolTipText(org.openide.util.NbBundle.getMessage(PartitionChooser.class, "PartitionChooser.refreshButton.toolTipText")); // NOI18N refreshButton.setFocusable(false); refreshButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); refreshButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); refreshToolbar.add(refreshButton); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL; gridBagConstraints.insets = new java.awt.Insets(2, 2, 0, 0); chooserPanel.add(refreshToolbar, gridBagConstraints); add(chooserPanel, java.awt.BorderLayout.PAGE_START); controlPanel.setOpaque(false); controlPanel.setLayout(new java.awt.GridBagLayout()); applyButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/gephi/desktop/partition/resources/apply.gif"))); // NOI18N applyButton.setText(org.openide.util.NbBundle.getMessage(PartitionChooser.class, "PartitionChooser.applyButton.text")); // NOI18N applyButton.setMargin(new java.awt.Insets(0, 14, 0, 14)); applyButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { applyButtonActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 0; gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHEAST; gridBagConstraints.weightx = 1.0; gridBagConstraints.insets = new java.awt.Insets(0, 0, 3, 5); controlPanel.add(applyButton, gridBagConstraints); groupLink.setClickedColor(new java.awt.Color(0, 51, 255)); groupLink.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/gephi/desktop/partition/resources/cluster.png"))); // NOI18N groupLink.setText(org.openide.util.NbBundle.getMessage(PartitionChooser.class, "PartitionChooser.groupLink.text")); // NOI18N groupLink.setToolTipText(org.openide.util.NbBundle.getMessage(PartitionChooser.class, "PartitionChooser.groupLink.toolTipText")); // NOI18N groupLink.setEnabled(false); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.insets = new java.awt.Insets(0, 4, 1, 0); controlPanel.add(groupLink, gridBagConstraints); pieLink.setClickedColor(new java.awt.Color(0, 51, 255)); pieLink.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/gephi/desktop/partition/resources/pie.png"))); // NOI18N pieLink.setText(org.openide.util.NbBundle.getMessage(PartitionChooser.class, "PartitionChooser.pieLink.text")); // NOI18N pieLink.setEnabled(false); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 0; gridBagConstraints.insets = new java.awt.Insets(0, 10, 1, 0); controlPanel.add(pieLink, gridBagConstraints); add(controlPanel, java.awt.BorderLayout.PAGE_END); centerScrollPane.setBorder(null); centerScrollPane.setOpaque(false); add(centerScrollPane, java.awt.BorderLayout.CENTER); }// </editor-fold>//GEN-END:initComponents private void applyButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_applyButtonActionPerformed PartitionController partitionController = Lookup.getDefault().lookup(PartitionController.class); partitionController.transform(model.getSelectedPartition(), model.getSelectedTransformer()); }//GEN-LAST:event_applyButtonActionPerformed private void initEvents() { partitionComboBox.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { if (partitionComboBox.getSelectedItem() == NO_SELECTION && model.getSelectedPartition() == null) { return; } if (partitionComboBox.getSelectedItem() == model.getSelectedPartition()) { return; } if (model.isWaiting()) { return; } PartitionController pc = Lookup.getDefault().lookup(PartitionController.class); pc.setSelectedPartition(partitionComboBox.getSelectedItem() == NO_SELECTION ? null : (Partition) partitionComboBox.getSelectedItem()); } }); groupLink.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (groupLink.getText().equals(GROUP_LABEL)) { PartitionController pc = Lookup.getDefault().lookup(PartitionController.class); pc.group(model.getSelectedPartition()); refreshGrouped(); } else { PartitionController pc = Lookup.getDefault().lookup(PartitionController.class); pc.ungroup(model.getSelectedPartition()); refreshGrouped(); } } }); pieLink.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { PartitionController pc = Lookup.getDefault().lookup(PartitionController.class); pc.showPie(pieLink.getText().equals(SHOW_PIE) ? true : false); } }); refreshButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { refreshBusyLabel.setVisible(true); refreshButton.setVisible(false); ((JXBusyLabel) refreshBusyLabel).setBusy(true); new Thread(new Runnable() { public void run() { PartitionController pc = Lookup.getDefault().lookup(PartitionController.class); pc.refreshPartitions(); SwingUtilities.invokeLater(new Runnable() { public void run() { ((JXBusyLabel) refreshBusyLabel).setBusy(false); refreshButton.setVisible(true); refreshBusyLabel.setVisible(false); refreshPartitions(); } }); } }).start(); } }); } private TransformerUI currentUI; private JPanel currentPanel; private void refreshTransformerBuilder() { if (currentUI != null) { currentUI.unsetup(); currentUI = null; currentPanel = null; } if (model.getSelectedTransformerBuilder() == null) { centerScrollPane.setViewportView(null); } else { Transformer t = model.getSelectedTransformer(); currentUI = model.getSelectedTransformerBuilder().getUI(); if (model.getSelectedPartition() != null) { currentPanel = currentUI.getPanel(); currentPanel.setOpaque(false); currentUI.setup(model.getSelectedPartition(), t); } } } private void refreshPartitions() { SwingUtilities.invokeLater(new Runnable() { public void run() { partitionComboBox.setModel(getComboBoxModel()); } }); } private DefaultComboBoxModel getComboBoxModel() { DefaultComboBoxModel comboBoxModel = new DefaultComboBoxModel(); Partition[] partitionArray = new Partition[0]; if (model.getSelectedPartitioning() == PartitionModel.NODE_PARTITIONING) { partitionArray = model.getNodePartitions(); } else if (model.getSelectedPartitioning() == PartitionModel.EDGE_PARTITIONING) { partitionArray = model.getEdgePartitions(); } Arrays.sort(partitionArray, new Comparator<Partition>() { public int compare(Partition a, Partition b) { return (a.toString().compareTo(b.toString())); } }); if (partitionArray.length > 0) { comboBoxModel.addElement(NO_SELECTION); for (Partition p : partitionArray) { comboBoxModel.addElement(p); if (p == model.getSelectedPartition()) { comboBoxModel.setSelectedItem(p); } } } return comboBoxModel; } private BusyLabel busyLabel; private void refreshWaiting() { if (model.isWaiting()) { busyLabel = BusyUtils.createCenteredBusyLabel(centerScrollPane, BUSY_MSG, null); busyLabel.setBusy(true); } else if (currentUI != null && currentPanel != null) { busyLabel.setBusy(false, currentPanel); } else if (busyLabel != null) { busyLabel.setBusy(false, null); } } private void refreshEnable() { if (model == null) { setEnable(false); if (currentUI != null) { centerScrollPane.setViewportView(null); currentUI.unsetup(); currentUI = null; currentPanel = null; } return; } setEnable(true); } private void refreshGrouped() { if (model.getSelectedPartitioning() == PartitionModel.NODE_PARTITIONING) { groupLink.setVisible(true); if (model.getSelectedPartition() != null) { PartitionController pc = Lookup.getDefault().lookup(PartitionController.class); if (pc.isGroupable(model.getSelectedPartition())) { groupLink.setText(GROUP_LABEL); groupLink.setEnabled(true); return; } else if (pc.isUngroupable(model.getSelectedPartition())) { groupLink.setText(UNGROUP_LABEL); groupLink.setEnabled(true); return; } } groupLink.setEnabled(false); } else { groupLink.setVisible(false); } } private PartitionPie partitionPie; private void refreshPie() { if (model.getSelectedPartition() != null) { pieLink.setEnabled(true); if (model.isPie()) { pieLink.setText(HIDE_PIE); partitionPie = new PartitionPie(); SwingUtilities.invokeLater(new Runnable() { public void run() { partitionPie.setup(model.getSelectedPartition()); remove(centerScrollPane); add(partitionPie, BorderLayout.CENTER); revalidate(); repaint(); } }); return; } else { pieLink.setText(SHOW_PIE); } } else { pieLink.setText(SHOW_PIE); pieLink.setEnabled(false); } if (!isAncestorOf(centerScrollPane)) { remove(partitionPie); add(centerScrollPane, BorderLayout.CENTER); revalidate(); repaint(); } } public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName().equals(PartitionModel.NODE_TRANSFORMER) || evt.getPropertyName().equals(PartitionModel.EDGE_TRANSFORMER)) { refreshTransformerBuilder(); } else if (evt.getPropertyName().equals(PartitionModel.NODE_PARTITION) || evt.getPropertyName().equals(PartitionModel.EDGE_PARTITION)) { refreshTransformerBuilder(); refreshPartitions(); refreshGrouped(); refreshPie(); } else if (evt.getPropertyName().equals(PartitionModel.WAITING)) { refreshWaiting(); } else if (evt.getPropertyName().equals(PartitionModel.SELECTED_PARTIONING)) { refreshTransformerBuilder(); refreshPartitions(); refreshGrouped(); refreshPie(); } else if (evt.getPropertyName().equals(PartitionModel.PIE)) { refreshPie(); } } private void refreshModel() { refreshEnable(); if (model != null) { refreshPartitions(); refreshTransformerBuilder(); refreshWaiting(); refreshGrouped(); refreshPie(); } } public void setup(PartitionModel model) { if (model != null) { this.model = model; model.addPropertyChangeListener(this); } refreshModel(); } public void unsetup() { if (model != null) { model.removePropertyChangeListener(this); model = null; } refreshModel(); } private void setEnable(boolean enable) { applyButton.setEnabled(enable); partitionComboBox.setEnabled(enable); groupLink.setEnabled(enable); pieLink.setEnabled(enable); refreshButton.setEnabled(enable); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton applyButton; private javax.swing.JScrollPane centerScrollPane; private javax.swing.JPanel chooserPanel; private javax.swing.JPanel controlPanel; private org.jdesktop.swingx.JXHyperlink groupLink; private javax.swing.JComboBox partitionComboBox; private org.jdesktop.swingx.JXHyperlink pieLink; private javax.swing.JLabel refreshBusyLabel; private javax.swing.JButton refreshButton; private javax.swing.JToolBar refreshToolbar; // End of variables declaration//GEN-END:variables }