/*
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
}