/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>, Mathieu Jacomy, Julian Bilcke, Eduardo Ramos
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.datalab;
import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.AWTEventListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.gephi.data.attributes.api.AttributeColumn;
import org.gephi.data.attributes.api.AttributeController;
import org.gephi.data.attributes.api.AttributeEvent;
import org.gephi.data.attributes.api.AttributeEvent.EventType;
import org.gephi.data.attributes.api.AttributeListener;
import org.gephi.data.attributes.api.AttributeModel;
import org.gephi.data.attributes.api.AttributeTable;
import org.gephi.datalab.api.DataLaboratoryHelper;
import org.gephi.datalab.api.datatables.DataTablesController;
import org.gephi.datalab.api.datatables.DataTablesEventListener;
import org.gephi.datalab.spi.ContextMenuItemManipulator;
import org.gephi.datalab.spi.columns.AttributeColumnsManipulator;
import org.gephi.datalab.spi.edges.EdgesManipulator;
import org.gephi.datalab.spi.general.GeneralActionsManipulator;
import org.gephi.datalab.spi.general.PluginGeneralActionsManipulator;
import org.gephi.datalab.spi.nodes.NodesManipulator;
import org.gephi.graph.api.Edge;
import org.gephi.graph.api.GraphController;
import org.gephi.graph.api.GraphEvent;
import org.gephi.graph.api.GraphListener;
import org.gephi.graph.api.GraphModel;
import org.gephi.graph.api.HierarchicalGraph;
import org.gephi.graph.api.Node;
import org.gephi.project.api.ProjectController;
import org.gephi.ui.utils.BusyUtils;
import org.gephi.project.api.Workspace;
import org.gephi.project.api.WorkspaceListener;
import org.gephi.ui.components.WrapLayout;
import org.gephi.desktop.datalab.general.actions.AddColumnUI;
import org.gephi.desktop.datalab.general.actions.CSVExportUI;
import org.gephi.desktop.datalab.general.actions.MergeColumnsUI;
import org.gephi.ui.utils.DialogFileFilter;
import org.gephi.ui.utils.UIUtils;
import org.gephi.utils.TableCSVExporter;
import org.netbeans.swing.etable.ETableColumnModel;
import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
import org.openide.util.Exceptions;
import org.openide.util.ImageUtilities;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
import org.openide.util.NbPreferences;
import org.openide.windows.TopComponent;
import org.openide.windows.WindowManager;
import org.pushingpixels.flamingo.api.common.CommandButtonDisplayState;
import org.pushingpixels.flamingo.api.common.JCommandButton;
import org.pushingpixels.flamingo.api.common.JCommandButtonPanel;
import org.pushingpixels.flamingo.api.common.JCommandButtonStrip;
import org.pushingpixels.flamingo.api.common.JCommandMenuButton;
import org.pushingpixels.flamingo.api.common.RichTooltip;
import org.pushingpixels.flamingo.api.common.icon.ImageWrapperResizableIcon;
import org.pushingpixels.flamingo.api.common.popup.JCommandPopupMenu;
import org.pushingpixels.flamingo.api.common.popup.JPopupPanel;
import org.pushingpixels.flamingo.api.common.popup.PopupPanelCallback;
/**
*
* @author Mathieu Bastian
*/
final class DataTableTopComponent extends TopComponent implements AWTEventListener, DataTablesEventListener, AttributeListener, GraphListener {
private enum ClassDisplayed {
NONE, NODE, EDGE
};
private static DataTableTopComponent instance;
static final String ICON_PATH = "org/gephi/desktop/datalab/resources/small.png";
private static final String PREFERRED_ID = "DataTableTopComponent";
//Settings
private static final String DATA_LABORATORY_DYNAMIC_FILTERING = "DataLaboratory_Dynamic_Filtering";
private static final String DATA_LABORATORY_ONLY_VISIBLE = "DataLaboratory_visibleOnly";
private static final String DATA_LABORATORY_SPARKLINES = "DataLaboratory_useSparklines";
private static final String DATA_LABORATORY_TIME_INTERVAL_GRAPHICS = "DataLaboratory_timeIntervalGraphics";
private static final String DATA_LABORATORY_EDGES_NODES_LABELS = "DataLaboratory_showEdgesNodesLabels";
private static final Color invalidFilterColor = new Color(254, 150, 150);
private final boolean dynamicFiltering;
private boolean visibleOnly = false;
private boolean useSparklines = false;
private boolean timeIntervalGraphics = false;
private boolean showEdgesNodesLabels = false;
private Map<Integer, ContextMenuItemManipulator> nodesActionMappings = new HashMap<Integer, ContextMenuItemManipulator>();//For key bindings
private Map<Integer, ContextMenuItemManipulator> edgesActionMappings = new HashMap<Integer, ContextMenuItemManipulator>();//For key bindings
//Data
private GraphModel graphModel;
private DataTablesModel dataTablesModel;
private AvailableColumnsModel nodeAvailableColumnsModel;
private AvailableColumnsModel edgeAvailableColumnsModel;
//Table
private NodeDataTable nodeTable;
private EdgeDataTable edgeTable;
//General actions buttons
private ArrayList<JComponent> generalActionsButtons = new ArrayList<JComponent>();
//States
private ClassDisplayed classDisplayed = ClassDisplayed.NODE;//Display nodes by default at first.
private ArrayList previousNodeFilterColumns = new ArrayList();
private int previousNodeColumnsFilterIndex = 0;
private ArrayList previousEdgeFilterColumns = new ArrayList();
private int previousEdgeColumnsFilterIndex = 0;
//Executor
private RefreshOnceHelperThread refreshOnceHelperThread;
private DataTableTopComponent() {
//Get saved preferences if existing:
dynamicFiltering = NbPreferences.forModule(DataTableTopComponent.class).getBoolean(DATA_LABORATORY_DYNAMIC_FILTERING, true);
visibleOnly = NbPreferences.forModule(DataTableTopComponent.class).getBoolean(DATA_LABORATORY_ONLY_VISIBLE, false);
useSparklines = NbPreferences.forModule(DataTableTopComponent.class).getBoolean(DATA_LABORATORY_SPARKLINES, false);
timeIntervalGraphics = NbPreferences.forModule(DataTableTopComponent.class).getBoolean(DATA_LABORATORY_TIME_INTERVAL_GRAPHICS, false);
showEdgesNodesLabels = NbPreferences.forModule(DataTableTopComponent.class).getBoolean(DATA_LABORATORY_EDGES_NODES_LABELS, false);
initComponents();
if (UIUtils.isAquaLookAndFeel()) {
columnManipulatorsPanel.setBackground(UIManager.getColor("NbExplorerView.background"));
}
columnManipulatorsPanel.setLayout(new WrapLayout(WrapLayout.CENTER, 25, 20));
setName(NbBundle.getMessage(DataTableTopComponent.class, "CTL_DataTableTopComponent"));
setIcon(ImageUtilities.loadImage(ICON_PATH));
//toolbar
Border b = (Border) UIManager.get("Nb.Editor.Toolbar.border"); //NOI18N
controlToolbar.setBorder(b);
if (UIUtils.isAquaLookAndFeel()) {
controlToolbar.setBackground(UIManager.getColor("NbExplorerView.background"));
}
initEvents();
//Init tables
nodeTable = new NodeDataTable();
edgeTable = new EdgeDataTable();
nodeTable.setUseSparklines(useSparklines);
nodeTable.setTimeIntervalGraphics(timeIntervalGraphics);
edgeTable.setUseSparklines(useSparklines);
edgeTable.setTimeIntervalGraphics(timeIntervalGraphics);
edgeTable.setShowEdgesNodesLabels(showEdgesNodesLabels);
//Init
ProjectController pc = Lookup.getDefault().lookup(ProjectController.class);
Workspace workspace = pc.getCurrentWorkspace();
if (workspace == null) {
clearAll();
} else {
AttributeModel attributeModel = Lookup.getDefault().lookup(AttributeController.class).getModel();
dataTablesModel = workspace.getLookup().lookup(DataTablesModel.class);
if (dataTablesModel == null) {
workspace.add(dataTablesModel = new DataTablesModel(attributeModel.getNodeTable(), attributeModel.getEdgeTable()));
}
nodeAvailableColumnsModel = dataTablesModel.getNodeAvailableColumnsModel();
edgeAvailableColumnsModel = dataTablesModel.getEdgeAvailableColumnsModel();
refreshAllOnce();
}
bannerPanel.setVisible(false);
}
private void initEvents() {
//Workspace Listener
ProjectController pc = Lookup.getDefault().lookup(ProjectController.class);
final GraphController gc = Lookup.getDefault().lookup(GraphController.class);
pc.addWorkspaceListener(new WorkspaceListener() {
public void initialize(Workspace workspace) {
//Prepare DataTablesEvent listener
Lookup.getDefault().lookup(DataTablesController.class).setDataTablesEventListener(DataTableTopComponent.this);
}
public void select(Workspace workspace) {
//Prepare DataTablesEvent listener
Lookup.getDefault().lookup(DataTablesController.class).setDataTablesEventListener(DataTableTopComponent.this);
AttributeModel attributeModel = Lookup.getDefault().lookup(AttributeController.class).getModel();
dataTablesModel = workspace.getLookup().lookup(DataTablesModel.class);
if (dataTablesModel == null) {
workspace.add(dataTablesModel = new DataTablesModel(attributeModel.getNodeTable(), attributeModel.getEdgeTable()));
}
nodeAvailableColumnsModel = dataTablesModel.getNodeAvailableColumnsModel();
edgeAvailableColumnsModel = dataTablesModel.getEdgeAvailableColumnsModel();
hideTable();
enableTableControls();
attributeModel.addAttributeListener(DataTableTopComponent.this);
graphModel = gc.getModel();
graphModel.addGraphListener(DataTableTopComponent.this);
refreshAllOnce();
}
public void unselect(Workspace workspace) {
graphModel.removeGraphListener(DataTableTopComponent.this);
AttributeModel attributeModel = workspace.getLookup().lookup(AttributeModel.class);
attributeModel.removeAttributeListener(DataTableTopComponent.this);
graphModel = null;
dataTablesModel = null;
nodeAvailableColumnsModel = null;
edgeAvailableColumnsModel = null;
clearAll();
}
public void close(Workspace workspace) {
}
public void disable() {
clearAll();
//No more workspaces active, disable the DataTablesEvent listener
Lookup.getDefault().lookup(DataTablesController.class).setDataTablesEventListener(null);
}
});
if (pc.getCurrentWorkspace() != null) {
//Prepare DataTablesEvent listener
Lookup.getDefault().lookup(DataTablesController.class).setDataTablesEventListener(DataTableTopComponent.this);
dataTablesModel = pc.getCurrentWorkspace().getLookup().lookup(DataTablesModel.class);
graphModel = gc.getModel();
graphModel.addGraphListener(DataTableTopComponent.this);
AttributeModel attributeModel = pc.getCurrentWorkspace().getLookup().lookup(AttributeModel.class);
attributeModel.addAttributeListener(DataTableTopComponent.this);
}
//Filter
if (dynamicFiltering) {
filterTextField.getDocument().addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent e) {
refreshFilter();
}
public void removeUpdate(DocumentEvent e) {
refreshFilter();
}
public void changedUpdate(DocumentEvent e) {
}
});
} else {
filterTextField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
refreshFilter();
}
});
}
columnComboBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
refreshFilter();
}
});
initKeyEventContextMenuActionMappings();
}
private void initKeyEventContextMenuActionMappings() {
mapItems(DataLaboratoryHelper.getDefault().getNodesManipulators(), nodesActionMappings);
mapItems(DataLaboratoryHelper.getDefault().getEdgesManipulators(), edgesActionMappings);
}
private void mapItems(ContextMenuItemManipulator[] items, Map<Integer, ContextMenuItemManipulator> map) {
Integer key;
ContextMenuItemManipulator[] subItems;
for (ContextMenuItemManipulator item : items) {
key = item.getMnemonicKey();
if (key != null) {
if (!map.containsKey(key)) {
map.put(key, item);
}
}
subItems = item.getSubItems();
if (subItems != null) {
mapItems(subItems, map);
}
}
}
private synchronized void refreshAll() {
if (Lookup.getDefault().lookup(ProjectController.class).getCurrentWorkspace() != null) {//Some workspace is selected
refreshTable();
refreshColumnManipulators();
refreshGeneralActionsButtons();
}
}
private void clearAll() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
clearTableControls();
clearColumnManipulators();
clearGeneralActionsButtons();
}
});
}
private AvailableColumnsModel getTableAvailableColumnsModel(AttributeTable table) {
if (Lookup.getDefault().lookup(AttributeController.class).getModel().getNodeTable() == table) {
return nodeAvailableColumnsModel;
} else {
return edgeAvailableColumnsModel;
}
}
public void attributesChanged(final AttributeEvent event) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
AvailableColumnsModel tableAvailableColumnsModel = getTableAvailableColumnsModel(event.getSource());
switch (event.getEventType()) {
case ADD_COLUMN:
for (AttributeColumn c : event.getData().getAddedColumns()) {
if (!tableAvailableColumnsModel.addAvailableColumn(c)) {//Add as available by default. Will only be added if the max number of available columns is not surpassed
availableColumnsButton.setIcon(ImageUtilities.loadImageIcon("org/gephi/desktop/datalab/resources/light-bulb--plus.png", true));
break;
}
}
break;
case REMOVE_COLUMN:
for (AttributeColumn c : event.getData().getAddedColumns()) {
tableAvailableColumnsModel.removeAvailableColumn(c);
}
break;
}
if (isOpened()) {
refreshOnce(event.is(EventType.SET_VALUE));
}
}
});
}
public void graphChanged(GraphEvent event) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (isOpened()) {
refreshOnce(false);
}
}
});
}
/**
* This method ensures that the refreshing of all Data laboratory or table only happens once in a short time period.
*
* @param refreshTableOnly True to refresh only table values, false to refresh all UI including manipulators
*/
private void refreshOnce(boolean refreshTableOnly) {
if (refreshOnceHelperThread == null || !refreshOnceHelperThread.isAlive() || (refreshOnceHelperThread.refreshTableOnly && !refreshTableOnly)) {
refreshOnceHelperThread = new RefreshOnceHelperThread(refreshTableOnly);
refreshOnceHelperThread.start();
} else {
refreshOnceHelperThread.eventAttended();
}
}
private void refreshAllOnce() {
refreshOnce(false);
}
/****************Table related methods:*****************/
private void refreshFilter() {
int index = columnComboBox.getSelectedIndex();
if (index < 0) {
return;
}
if (classDisplayed.equals(ClassDisplayed.NODE)) {
if (nodeTable.setFilter(filterTextField.getText(), index)) {
filterTextField.setBackground(Color.WHITE);
} else {
filterTextField.setBackground(invalidFilterColor);
}
previousNodeColumnsFilterIndex = index;
} else if (classDisplayed.equals(ClassDisplayed.EDGE)) {
if (edgeTable.setPattern(filterTextField.getText(), index)) {
filterTextField.setBackground(Color.WHITE);
} else {
filterTextField.setBackground(invalidFilterColor);
}
previousEdgeColumnsFilterIndex = index;
}
}
private void initNodesView() {
Runnable initNodesRunnable = new Runnable() {
public void run() {
try {
String busyMsg = NbBundle.getMessage(DataTableTopComponent.class, "DataTableTopComponent.tableScrollPane.busyMessage");
BusyUtils.BusyLabel busylabel = BusyUtils.createCenteredBusyLabel(tableScrollPane, busyMsg, nodeTable.getOutlineTable());
busylabel.setBusy(true);
//Attributes columns
final AttributeColumn[] cols = nodeAvailableColumnsModel.getAvailableColumns();
//Nodes from DHNS
HierarchicalGraph graph;
if (visibleOnly) {
graph = graphModel.getHierarchicalGraphVisible();
} else {
graph = graphModel.getHierarchicalGraph();
}
if (graph == null) {
tableScrollPane.setViewportView(null);
return;
}
//Model
nodeTable.refreshModel(graph, cols, dataTablesModel);
refreshFilterColumns();
busylabel.setBusy(false);
nodeTable.scrollToFirstNodeSelected();
} catch (Exception e) {
Exceptions.printStackTrace(e);
JLabel errorLabel = new JLabel(NbBundle.getMessage(DataTableTopComponent.class, "DataTableTopComponent.tableScrollPane.error"), SwingConstants.CENTER);
tableScrollPane.setViewportView(errorLabel);
}
}
};
SwingUtilities.invokeLater(initNodesRunnable);
}
private void initEdgesView() {
Runnable initEdgesRunnable = new Runnable() {
public void run() {
try {
String busyMsg = NbBundle.getMessage(DataTableTopComponent.class, "DataTableTopComponent.tableScrollPane.busyMessage");
BusyUtils.BusyLabel busylabel = BusyUtils.createCenteredBusyLabel(tableScrollPane, busyMsg, edgeTable.getTable());
busylabel.setBusy(true);
//Attributes columns
final AttributeColumn[] cols = edgeAvailableColumnsModel.getAvailableColumns();
//Edges from DHNS
HierarchicalGraph graph;
if (visibleOnly) {
graph = graphModel.getHierarchicalGraphVisible();
} else {
graph = graphModel.getHierarchicalGraph();
}
if (graph == null) {
tableScrollPane.setViewportView(null);
return;
}
//Model
edgeTable.refreshModel(graph, cols, dataTablesModel);
refreshFilterColumns();
busylabel.setBusy(false);
edgeTable.scrollToFirstEdgeSelected();
} catch (Exception e) {
Exceptions.printStackTrace(e);
JLabel errorLabel = new JLabel(NbBundle.getMessage(DataTableTopComponent.class, "DataTableTopComponent.tableScrollPane.error"), SwingConstants.CENTER);
tableScrollPane.setViewportView(errorLabel);
}
}
};
SwingUtilities.invokeLater(initEdgesRunnable);
}
private void refreshFilterColumns() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
ArrayList columns = new ArrayList();
if (classDisplayed.equals(ClassDisplayed.NODE)) {
ETableColumnModel columnModel = (ETableColumnModel) nodeTable.getOutlineTable().getColumnModel();
DefaultComboBoxModel model = new DefaultComboBoxModel();
for (int i = 0; i < columnModel.getColumnCount(); i++) {
if (!columnModel.isColumnHidden(columnModel.getColumn(i))) {
model.addElement(columnModel.getColumn(i).getHeaderValue());
columns.add(columnModel.getColumn(i).getHeaderValue());
}
}
columnComboBox.setModel(model);
if (columns.equals(previousNodeFilterColumns) && previousNodeColumnsFilterIndex < columnComboBox.getItemCount()) {//Preserve user selected column when the columns list does not change
columnComboBox.setSelectedIndex(previousNodeColumnsFilterIndex);
} else {
previousNodeColumnsFilterIndex = 0;
}
previousNodeFilterColumns = columns;
} else if (classDisplayed.equals(ClassDisplayed.EDGE)) {
DefaultComboBoxModel model = new DefaultComboBoxModel();
for (int i = 0; i < edgeTable.getTable().getColumnCount(); i++) {
if (edgeTable.getTable().getColumnExt(i).isVisible()) {
model.addElement(edgeTable.getTable().getColumnExt(i).getTitle());
columns.add(edgeTable.getTable().getColumnExt(i).getTitle());
}
}
columnComboBox.setModel(model);
if (columns.equals(previousEdgeFilterColumns) && previousEdgeColumnsFilterIndex < columnComboBox.getItemCount()) {//Preserve user selected column when the columns list does not change
columnComboBox.setSelectedIndex(previousEdgeColumnsFilterIndex);
} else {
previousEdgeColumnsFilterIndex = 0;
}
previousEdgeFilterColumns = columns;
}
}
});
}
private void enableTableControls() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
nodesButton.setEnabled(true);
edgesButton.setEnabled(true);
configurationButton.setEnabled(true);
availableColumnsButton.setEnabled(true);
filterTextField.setEnabled(true);
columnComboBox.setEnabled(true);
labelFilter.setEnabled(true);
}
});
}
private void clearTableControls() {
elementGroup.clearSelection();
nodesButton.setEnabled(false);
edgesButton.setEnabled(false);
configurationButton.setEnabled(false);
filterTextField.setEnabled(false);
filterTextField.setText("");
columnComboBox.setEnabled(false);
columnComboBox.removeAllItems();
previousNodeFilterColumns.clear();
previousEdgeFilterColumns.clear();
availableColumnsButton.setEnabled(false);
availableColumnsButton.setIcon(ImageUtilities.loadImageIcon("org/gephi/desktop/datalab/resources/light-bulb.png", true));
labelFilter.setEnabled(false);
bannerPanel.setVisible(false);
hideTable();
}
private void hideTable() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
tableScrollPane.setViewportView(null);
}
});
}
private void refreshTable() {
bannerPanel.setVisible(false);
if (classDisplayed.equals(ClassDisplayed.NODE)) {
nodesButton.setSelected(true);
initNodesView();
} else if (classDisplayed.equals(ClassDisplayed.EDGE)) {
edgesButton.setSelected(true);
initEdgesView();
}
}
public void selectNodesTable() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
classDisplayed = ClassDisplayed.NODE;
refreshAllOnce();
}
});
}
public void selectEdgesTable() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
classDisplayed = ClassDisplayed.EDGE;
refreshAllOnce();
}
});
}
public void refreshCurrentTable() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
refreshOnce(true);
}
});
}
public void setNodeTableSelection(final Node[] nodes) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
nodeTable.setNodesSelection(nodes);
nodeTable.scrollToFirstNodeSelected();
}
});
}
public void setEdgeTableSelection(final Edge[] edges) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
edgeTable.setEdgesSelection(edges);
edgeTable.scrollToFirstEdgeSelected();
}
});
}
public Node[] getNodeTableSelection() {
return nodeTable.getNodesFromSelectedRows();
}
public Edge[] getEdgeTableSelection() {
return edgeTable.getEdgesFromSelectedRows();
}
public boolean isNodeTableMode() {
return classDisplayed == ClassDisplayed.NODE;
}
public boolean isEdgeTableMode() {
return classDisplayed == ClassDisplayed.EDGE;
}
public boolean isShowOnlyVisible() {
return visibleOnly;
}
public void setShowOnlyVisible(boolean showOnlyVisible) {
visibleOnly = showOnlyVisible;
refreshCurrentTable();
}
public boolean isUseSparklines() {
return useSparklines;
}
public void setUseSparklines(boolean useSparklines) {
this.useSparklines = useSparklines;
nodeTable.setUseSparklines(useSparklines);
edgeTable.setUseSparklines(useSparklines);
refreshCurrentTable();
}
public boolean isTimeIntervalGraphics() {
return timeIntervalGraphics;
}
public void setTimeIntervalGraphics(boolean timeIntervalGraphics) {
this.timeIntervalGraphics = timeIntervalGraphics;
nodeTable.setTimeIntervalGraphics(timeIntervalGraphics);
edgeTable.setTimeIntervalGraphics(timeIntervalGraphics);
refreshCurrentTable();
}
public boolean isShowEdgesNodesLabels() {
return showEdgesNodesLabels;
}
public void setShowEdgesNodesLabels(boolean showEdgesNodesLabels) {
this.showEdgesNodesLabels = showEdgesNodesLabels;
edgeTable.setShowEdgesNodesLabels(showEdgesNodesLabels);
refreshCurrentTable();
}
public void exportCurrentTable(ExportMode exportMode) {
JTable table;
if (classDisplayed == classDisplayed.NODE) {
table = nodeTable.getOutlineTable();
} else {
table = edgeTable.getTable();
}
switch (exportMode) {
case CSV:
showCSVExportUI(table);
break;
}
}
private void showCSVExportUI(JTable table) {
CSVExportUI csvUI = new CSVExportUI(table);
DialogDescriptor dd = new DialogDescriptor(csvUI, csvUI.getDisplayName());
if (DialogDisplayer.getDefault().notify(dd).equals(DialogDescriptor.OK_OPTION)) {
DataTableTopComponent.exportTableAsCSV(this, table, csvUI.getSelectedSeparator(), csvUI.getSelectedCharset(), csvUI.getSelectedColumnsIndexes());
}
csvUI.unSetup();
}
/*************Column manipulators related methods:*************/
private void refreshColumnManipulators() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
clearColumnManipulators();
prepareAddColumnButton();
prepareMergeColumnsButton();
prepareColumnManipulatorsButtons();
}
});
}
private void clearColumnManipulators() {
columnManipulatorsPanel.removeAll();
columnManipulatorsPanel.updateUI();
}
/**
* Creates the buttons that call the AttributeColumnManipulators.
*/
private void prepareColumnManipulatorsButtons() {
AttributeModel attributeModel = Lookup.getDefault().lookup(ProjectController.class).getCurrentWorkspace().getLookup().lookup(AttributeModel.class);
AttributeTable table;
AttributeColumn[] columns;
if (classDisplayed == ClassDisplayed.NODE) {
table = attributeModel.getNodeTable();
columns = nodeAvailableColumnsModel.getAvailableColumns();
} else {
table = attributeModel.getEdgeTable();
columns = edgeAvailableColumnsModel.getAvailableColumns();
}
DataLaboratoryHelper dlh = DataLaboratoryHelper.getDefault();
AttributeColumnsManipulator[] manipulators = dlh.getAttributeColumnsManipulators();
JCommandButtonStrip currentButtonGroup = new JCommandButtonStrip(JCommandButtonStrip.StripOrientation.HORIZONTAL);
currentButtonGroup.setDisplayState(CommandButtonDisplayState.BIG);
Integer lastManipulatorType = null;
for (AttributeColumnsManipulator acm : manipulators) {
if (lastManipulatorType == null) {
lastManipulatorType = acm.getType();
}
if (lastManipulatorType != acm.getType()) {
columnManipulatorsPanel.add(currentButtonGroup);
currentButtonGroup = new JCommandButtonStrip(JCommandButtonStrip.StripOrientation.HORIZONTAL);
currentButtonGroup.setDisplayState(CommandButtonDisplayState.BIG);
}
lastManipulatorType = acm.getType();
currentButtonGroup.add(prepareJCommandButton(table, columns, acm));
}
columnManipulatorsPanel.add(currentButtonGroup);
}
/**
* Creates a JCommandButton for the specified columns of a table and AttributeColumnsManipulator
* @param table table
* @param columns Columns
* @param acm AttributeColumnsManipulator
* @return Prepared JCommandButton
*/
private JCommandButton prepareJCommandButton(final AttributeTable table, final AttributeColumn[] columns, final AttributeColumnsManipulator acm) {
JCommandButton manipulatorButton;
if (acm.getIcon() != null) {
manipulatorButton = new JCommandButton(acm.getName(), ImageWrapperResizableIcon.getIcon(acm.getIcon(), new Dimension(16, 16)));
} else {
manipulatorButton = new JCommandButton(acm.getName());
}
manipulatorButton.setCommandButtonKind(JCommandButton.CommandButtonKind.POPUP_ONLY);
manipulatorButton.setDisplayState(CommandButtonDisplayState.MEDIUM);
if (acm.getDescription() != null && !acm.getDescription().isEmpty()) {
manipulatorButton.setPopupRichTooltip(new RichTooltip(NbBundle.getMessage(DataTableTopComponent.class, "DataTableTopComponent.RichToolTip.title.text"), acm.getDescription()));
}
final ArrayList<AttributeColumn> availableColumns = new ArrayList<AttributeColumn>();
for (final AttributeColumn column : columns) {
if (acm.canManipulateColumn(table, column)) {
availableColumns.add(column);
}
}
if (!availableColumns.isEmpty()) {
manipulatorButton.setPopupCallback(new PopupPanelCallback() {
public JPopupPanel getPopupPanel(JCommandButton jcb) {
JCommandPopupMenu popup = new JCommandPopupMenu();
JCommandMenuButton button;
for (final AttributeColumn column : availableColumns) {
button = new JCommandMenuButton(column.getTitle(), ImageWrapperResizableIcon.getIcon(ImageUtilities.loadImage("org/gephi/desktop/datalab/resources/column.png"), new Dimension(16, 16)));
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
DataLaboratoryHelper.getDefault().executeAttributeColumnsManipulator(acm, table, column);
}
});
popup.addMenuButton(button);
}
return popup;
}
});
} else {
manipulatorButton.setEnabled(false);
}
return manipulatorButton;
}
/**
* Create the special Add new column button.
*/
private void prepareAddColumnButton() {
JCommandButtonStrip strip = new JCommandButtonStrip(JCommandButtonStrip.StripOrientation.HORIZONTAL);
strip.setDisplayState(CommandButtonDisplayState.BIG);
JCommandButton button = new JCommandButton(NbBundle.getMessage(DataTableTopComponent.class, "DataTableTopComponent.addColumnButton.text"), ImageWrapperResizableIcon.getIcon(ImageUtilities.loadImage("org/gephi/desktop/datalab/resources/table-insert-column.png", true), new Dimension(16, 16)));
button.setCommandButtonKind(JCommandButton.CommandButtonKind.ACTION_ONLY);
button.setDisplayState(CommandButtonDisplayState.BIG);
if (classDisplayed == ClassDisplayed.NODE) {
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showAddColumnUI(AddColumnUI.Mode.NODES_TABLE);
}
});
} else {
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showAddColumnUI(AddColumnUI.Mode.EDGES_TABLE);
}
});
}
strip.add(button);
columnManipulatorsPanel.add(strip);
}
/**
* Create the special merge columns button.
*/
private void prepareMergeColumnsButton() {
JCommandButtonStrip strip = new JCommandButtonStrip(JCommandButtonStrip.StripOrientation.HORIZONTAL);
strip.setDisplayState(CommandButtonDisplayState.BIG);
JCommandButton button = new JCommandButton(NbBundle.getMessage(DataTableTopComponent.class, "DataTableTopComponent.mergeColumnsButton.text"), ImageWrapperResizableIcon.getIcon(ImageUtilities.loadImage("org/gephi/desktop/datalab/resources/merge.png", true), new Dimension(16, 16)));
button.setCommandButtonKind(JCommandButton.CommandButtonKind.ACTION_ONLY);
button.setDisplayState(CommandButtonDisplayState.BIG);
if (classDisplayed == ClassDisplayed.NODE) {
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showMergeColumnsUI(MergeColumnsUI.Mode.NODES_TABLE);
}
});
} else {
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showMergeColumnsUI(MergeColumnsUI.Mode.EDGES_TABLE);
}
});
}
strip.add(button);
columnManipulatorsPanel.add(strip);
}
private void showAddColumnUI(AddColumnUI.Mode mode) {
JButton okButton = new JButton(NbBundle.getMessage(DataTableTopComponent.class, "DataTableTopComponent.dialogs.okButton.text"));
AddColumnUI addColumnUI = new AddColumnUI();
addColumnUI.setup(mode);
addColumnUI.setOkButton(okButton);
DialogDescriptor dd = new DialogDescriptor(AddColumnUI.createValidationPanel(addColumnUI), addColumnUI.getDisplayName());
dd.setOptions(new Object[]{okButton, DialogDescriptor.CANCEL_OPTION});
if (DialogDisplayer.getDefault().notify(dd).equals(okButton)) {
addColumnUI.execute();
}
addColumnUI.unSetup();
}
private void showMergeColumnsUI(MergeColumnsUI.Mode mode) {
JButton okButton = new JButton(NbBundle.getMessage(DataTableTopComponent.class, "DataTableTopComponent.dialogs.okButton.text"));
MergeColumnsUI mergeColumnsUI = new MergeColumnsUI();
mergeColumnsUI.setup(mode);
mergeColumnsUI.setOkButton(okButton);
DialogDescriptor dd = new DialogDescriptor(MergeColumnsUI.createValidationPanel(mergeColumnsUI), mergeColumnsUI.getDisplayName());
dd.setOptions(new Object[]{okButton, DialogDescriptor.CANCEL_OPTION});
if (DialogDisplayer.getDefault().notify(dd).equals(okButton)) {
mergeColumnsUI.execute();
}
}
/**************General actions manipulators related methods:***************/
private void refreshGeneralActionsButtons() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
clearGeneralActionsButtons();
prepareGeneralActionsButtons();
}
});
}
private void clearGeneralActionsButtons() {
for (JComponent b : generalActionsButtons) {
controlToolbar.remove(b);
}
generalActionsButtons.clear();
controlToolbar.updateUI();
}
/**
* Adds the buttons for the GeneralActionsManipulators.
*/
public void prepareGeneralActionsButtons() {
//Figure out the index to place the buttons, in order to put them between separator 2 and the boxGlue.
int index = controlToolbar.getComponentIndex(boxGlue);
final DataLaboratoryHelper dlh = DataLaboratoryHelper.getDefault();
JButton button;
for (final GeneralActionsManipulator m : dlh.getGeneralActionsManipulators()) {
button = new JButton(m.getName(), m.getIcon());
if (m.getDescription() != null && !m.getDescription().isEmpty()) {
button.setToolTipText(m.getDescription());
}
if (m.canExecute()) {
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dlh.executeManipulator(m);
}
});
} else {
button.setEnabled(false);
}
controlToolbar.add(button, index);
index++;
generalActionsButtons.add(button);
}
//Add plugin general actions as a drop down list:
final PluginGeneralActionsManipulator[] plugins = dlh.getPluginGeneralActionsManipulators();
if (plugins != null && plugins.length > 0) {
JCommandButton pluginsButton = new JCommandButton(NbBundle.getMessage(DataTableTopComponent.class, "DataTableTopComponent.general.actions.plugins.button.text"), ImageWrapperResizableIcon.getIcon(ImageUtilities.loadImage("org/gephi/desktop/datalab/resources/puzzle--arrow.png", true), new Dimension(16, 16)));
pluginsButton.setDisplayState(CommandButtonDisplayState.MEDIUM);
pluginsButton.setCommandButtonKind(JCommandButton.CommandButtonKind.POPUP_ONLY);
pluginsButton.setPopupCallback(new PopupPanelCallback() {
public JPopupPanel getPopupPanel(JCommandButton jcb) {
JCommandButtonPanel pluginsPanel = new JCommandButtonPanel(CommandButtonDisplayState.BIG);
Integer lastManipulatorType = null;
int group = 1;
pluginsPanel.addButtonGroup(NbBundle.getMessage(DataTableTopComponent.class, "DataTableTopComponent.general.actions.plugins.group.name", group));
for (final PluginGeneralActionsManipulator m : plugins) {
if (lastManipulatorType == null) {
lastManipulatorType = m.getType();
}
if (lastManipulatorType != m.getType()) {
group++;
pluginsPanel.addButtonGroup(NbBundle.getMessage(DataTableTopComponent.class, "DataTableTopComponent.general.actions.plugins.group.name", group));
}
lastManipulatorType = m.getType();
pluginsPanel.addButtonToLastGroup(preparePluginGeneralActionsButton(m));
}
JCommandPopupMenu popup = new JCommandPopupMenu(pluginsPanel, 8, 8);
return popup;
}
});
controlToolbar.add(pluginsButton, index);
generalActionsButtons.add(pluginsButton);
}
controlToolbar.updateUI();
}
/**
* Prepare a button for the popup panel for plugin general actions.
* @param m PluginGeneralActionsManipulator for the button
* @return JCommandButton for the manipulator
*/
private JCommandButton preparePluginGeneralActionsButton(final PluginGeneralActionsManipulator m) {
JCommandButton button = new JCommandButton(m.getName(), m.getIcon() != null ? ImageWrapperResizableIcon.getIcon(ImageUtilities.icon2Image(m.getIcon()), new Dimension(16, 16)) : null);//Convert icon to Image if it is not null
button.setDisplayState(CommandButtonDisplayState.BIG);
button.setCommandButtonKind(JCommandButton.CommandButtonKind.ACTION_ONLY);
if (m.getDescription() != null && !m.getDescription().isEmpty()) {
button.setToolTipText(m.getDescription());
}
if (m.canExecute()) {
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
DataLaboratoryHelper.getDefault().executeManipulator(m);
}
});
} else {
button.setEnabled(false);
}
return button;
}
/**
* This thread is used for processing graphChanged and attributesChanged events.
* It takes care to only refresh the UI once (the last one) when a lot of events come in a short period of time.
*/
class RefreshOnceHelperThread extends Thread {
private static final int CHECK_TIME_INTERVAL = 100;//100 ms.
private volatile boolean moreEvents = false;
private boolean refreshTableOnly;
public RefreshOnceHelperThread() {
refreshTableOnly = false;
}
public RefreshOnceHelperThread(boolean refreshTableOnly) {
this.refreshTableOnly = refreshTableOnly;
}
@Override
public void run() {
try {
do {
moreEvents = false;
Thread.sleep(CHECK_TIME_INTERVAL);
} while (moreEvents);
if (refreshTableOnly) {
DataTableTopComponent.this.refreshTable();
} else {
DataTableTopComponent.this.refreshAll();
}
} catch (InterruptedException ex) {
Exceptions.printStackTrace(ex);
}
}
public void eventAttended() {
this.moreEvents = true;
}
}
/**
* To react to Ctrl+F keys combination calling Search/Replace general action
* (and nodes/edges context menu mappings)
* @param event
*/
public void eventDispatched(AWTEvent event) {
KeyEvent evt = (KeyEvent) event;
if (evt.getID() == KeyEvent.KEY_RELEASED && (evt.getModifiersEx() & KeyEvent.CTRL_DOWN_MASK) != 0) {
DataLaboratoryHelper dlh = DataLaboratoryHelper.getDefault();
if (evt.getKeyCode() == KeyEvent.VK_F) {//Call Search replace with 'F' without general actions key mappings support:
GeneralActionsManipulator gam = dlh.getGeneralActionsManipulatorByName("SearchReplace");
if (gam != null) {
dlh.executeManipulator(gam);
}
evt.consume();
} else {//Nodes/edges mappings:
if (classDisplayed == ClassDisplayed.NODE) {
final ContextMenuItemManipulator item = nodesActionMappings.get(evt.getKeyCode());
if (item != null) {
Node[] nodes = nodeTable.getNodesFromSelectedRows();
if (nodes.length > 0) {
((NodesManipulator) item).setup(nodes, nodes[0]);
if (item.isAvailable() && item.canExecute()) {
DataLaboratoryHelper.getDefault().executeManipulator(item);
}
}
evt.consume();
}
} else if (classDisplayed == ClassDisplayed.EDGE) {
final ContextMenuItemManipulator item = edgesActionMappings.get(evt.getKeyCode());
if (item != null) {
Edge[] edges = edgeTable.getEdgesFromSelectedRows();
if (edges.length > 0) {
((EdgesManipulator) item).setup(edges, edges[0]);
if (item.isAvailable() && item.canExecute()) {
DataLaboratoryHelper.getDefault().executeManipulator(item);
}
}
evt.consume();
}
}
}
}
}
/** 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.
*/
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
java.awt.GridBagConstraints gridBagConstraints;
elementGroup = new javax.swing.ButtonGroup();
controlToolbar = new javax.swing.JToolBar();
nodesButton = new javax.swing.JToggleButton();
edgesButton = new javax.swing.JToggleButton();
separator = new javax.swing.JToolBar.Separator();
configurationButton = new javax.swing.JButton();
separator2 = new javax.swing.JToolBar.Separator();
boxGlue = new javax.swing.JLabel();
labelFilter = new org.jdesktop.swingx.JXLabel();
filterTextField = new javax.swing.JTextField();
columnComboBox = new javax.swing.JComboBox();
availableColumnsButton = new javax.swing.JButton();
tableScrollPane = new javax.swing.JScrollPane();
bannerPanel = new javax.swing.JPanel();
labelBanner = new javax.swing.JLabel();
refreshButton = new javax.swing.JButton();
attributeColumnsScrollPane = new javax.swing.JScrollPane();
columnManipulatorsPanel = new javax.swing.JPanel();
setLayout(new java.awt.GridBagLayout());
controlToolbar.setFloatable(false);
controlToolbar.setRollover(true);
elementGroup.add(nodesButton);
org.openide.awt.Mnemonics.setLocalizedText(nodesButton, org.openide.util.NbBundle.getMessage(DataTableTopComponent.class, "DataTableTopComponent.nodesButton.text")); // NOI18N
nodesButton.setFocusable(false);
nodesButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
nodesButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
nodesButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
nodesButtonActionPerformed(evt);
}
});
controlToolbar.add(nodesButton);
elementGroup.add(edgesButton);
org.openide.awt.Mnemonics.setLocalizedText(edgesButton, org.openide.util.NbBundle.getMessage(DataTableTopComponent.class, "DataTableTopComponent.edgesButton.text")); // NOI18N
edgesButton.setFocusable(false);
edgesButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
edgesButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
edgesButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
edgesButtonActionPerformed(evt);
}
});
controlToolbar.add(edgesButton);
controlToolbar.add(separator);
configurationButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/gephi/desktop/datalab/resources/gear-small.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(configurationButton, org.openide.util.NbBundle.getMessage(DataTableTopComponent.class, "DataTableTopComponent.configurationButton.text")); // NOI18N
configurationButton.setFocusable(false);
configurationButton.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
configurationButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
configurationButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
configurationButtonActionPerformed(evt);
}
});
controlToolbar.add(configurationButton);
controlToolbar.add(separator2);
org.openide.awt.Mnemonics.setLocalizedText(boxGlue, org.openide.util.NbBundle.getMessage(DataTableTopComponent.class, "DataTableTopComponent.boxGlue.text")); // NOI18N
boxGlue.setMaximumSize(new java.awt.Dimension(32767, 32767));
controlToolbar.add(boxGlue);
org.openide.awt.Mnemonics.setLocalizedText(labelFilter, org.openide.util.NbBundle.getMessage(DataTableTopComponent.class, "DataTableTopComponent.labelFilter.text")); // NOI18N
controlToolbar.add(labelFilter);
filterTextField.setText(org.openide.util.NbBundle.getMessage(DataTableTopComponent.class, "DataTableTopComponent.filterTextField.text")); // NOI18N
filterTextField.setToolTipText(org.openide.util.NbBundle.getMessage(DataTableTopComponent.class, "DataTableTopComponent.filterTextField.toolTipText")); // NOI18N
filterTextField.setMaximumSize(new java.awt.Dimension(1000, 30));
filterTextField.setPreferredSize(new java.awt.Dimension(150, 20));
controlToolbar.add(filterTextField);
columnComboBox.setMaximumSize(new java.awt.Dimension(2000, 20));
columnComboBox.setPreferredSize(new java.awt.Dimension(120, 20));
controlToolbar.add(columnComboBox);
availableColumnsButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/gephi/desktop/datalab/resources/light-bulb.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(availableColumnsButton, org.openide.util.NbBundle.getMessage(DataTableTopComponent.class, "DataTableTopComponent.availableColumnsButton.text")); // NOI18N
availableColumnsButton.setToolTipText(org.openide.util.NbBundle.getMessage(DataTableTopComponent.class, "DataTableTopComponent.availableColumnsButton.toolTipText")); // NOI18N
availableColumnsButton.setFocusable(false);
availableColumnsButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
availableColumnsButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
availableColumnsButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
availableColumnsButtonActionPerformed(evt);
}
});
controlToolbar.add(availableColumnsButton);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 1;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
add(controlToolbar, gridBagConstraints);
tableScrollPane.setMinimumSize(new java.awt.Dimension(100, 100));
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 2;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.weighty = 1.0;
add(tableScrollPane, gridBagConstraints);
bannerPanel.setBackground(new java.awt.Color(178, 223, 240));
bannerPanel.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, Color.BLACK));
bannerPanel.setLayout(new java.awt.GridBagLayout());
labelBanner.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/gephi/desktop/datalab/resources/info.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(labelBanner, org.openide.util.NbBundle.getMessage(DataTableTopComponent.class, "DataTableTopComponent.labelBanner.text")); // NOI18N
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0;
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.insets = new java.awt.Insets(2, 5, 2, 0);
bannerPanel.add(labelBanner, gridBagConstraints);
org.openide.awt.Mnemonics.setLocalizedText(refreshButton, org.openide.util.NbBundle.getMessage(DataTableTopComponent.class, "DataTableTopComponent.refreshButton.text")); // NOI18N
refreshButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
refreshButtonActionPerformed(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 0;
gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.insets = new java.awt.Insets(1, 0, 1, 1);
bannerPanel.add(refreshButton, gridBagConstraints);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
gridBagConstraints.weightx = 1.0;
add(bannerPanel, gridBagConstraints);
attributeColumnsScrollPane.setMinimumSize(new java.awt.Dimension(200, 100));
attributeColumnsScrollPane.setPreferredSize(new java.awt.Dimension(200, 100));
columnManipulatorsPanel.setMinimumSize(new java.awt.Dimension(200, 100));
columnManipulatorsPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 25, 20));
attributeColumnsScrollPane.setViewportView(columnManipulatorsPanel);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 3;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
add(attributeColumnsScrollPane, gridBagConstraints);
}// </editor-fold>//GEN-END:initComponents
private void refreshButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refreshButtonActionPerformed
refreshCurrentTable();
}//GEN-LAST:event_refreshButtonActionPerformed
private void edgesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_edgesButtonActionPerformed
selectEdgesTable();
}//GEN-LAST:event_edgesButtonActionPerformed
private void nodesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nodesButtonActionPerformed
selectNodesTable();
}//GEN-LAST:event_nodesButtonActionPerformed
private void configurationButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_configurationButtonActionPerformed
DialogDescriptor dd = new DialogDescriptor(new ConfigurationPanel(this), NbBundle.getMessage(DataTableTopComponent.class, "ConfigurationPanel.title"));
dd.setOptions(new Object[]{DialogDescriptor.OK_OPTION});
DialogDisplayer.getDefault().notify(dd);
//Save preferences:
NbPreferences.forModule(DataTableTopComponent.class).putBoolean(DATA_LABORATORY_ONLY_VISIBLE, visibleOnly);
NbPreferences.forModule(DataTableTopComponent.class).putBoolean(DATA_LABORATORY_SPARKLINES, useSparklines);
NbPreferences.forModule(DataTableTopComponent.class).putBoolean(DATA_LABORATORY_TIME_INTERVAL_GRAPHICS, timeIntervalGraphics);
NbPreferences.forModule(DataTableTopComponent.class).putBoolean(DATA_LABORATORY_EDGES_NODES_LABELS, showEdgesNodesLabels);
}//GEN-LAST:event_configurationButtonActionPerformed
private void availableColumnsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_availableColumnsButtonActionPerformed
AttributeTable table;
AvailableColumnsModel availableColumnsModel;
if (classDisplayed == classDisplayed.NODE) {
table = Lookup.getDefault().lookup(AttributeController.class).getModel().getNodeTable();
} else {
table = Lookup.getDefault().lookup(AttributeController.class).getModel().getEdgeTable();
}
availableColumnsModel = getTableAvailableColumnsModel(table);
DialogDescriptor dd = new DialogDescriptor(new AvailableColumnsPanel(table, availableColumnsModel).getValidationPanel(), NbBundle.getMessage(DataTableTopComponent.class, "AvailableColumnsPanel.title"));
dd.setOptions(new Object[]{DialogDescriptor.OK_OPTION});
DialogDisplayer.getDefault().notify(dd);
refreshAllOnce();
availableColumnsButton.setIcon(ImageUtilities.loadImageIcon("org/gephi/desktop/datalab/resources/light-bulb.png", true));
}//GEN-LAST:event_availableColumnsButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JScrollPane attributeColumnsScrollPane;
private javax.swing.JButton availableColumnsButton;
private javax.swing.JPanel bannerPanel;
private javax.swing.JLabel boxGlue;
private javax.swing.JComboBox columnComboBox;
private javax.swing.JPanel columnManipulatorsPanel;
private javax.swing.JButton configurationButton;
private javax.swing.JToolBar controlToolbar;
private javax.swing.JToggleButton edgesButton;
private javax.swing.ButtonGroup elementGroup;
private javax.swing.JTextField filterTextField;
private javax.swing.JLabel labelBanner;
private org.jdesktop.swingx.JXLabel labelFilter;
private javax.swing.JToggleButton nodesButton;
private javax.swing.JButton refreshButton;
private javax.swing.JToolBar.Separator separator;
private javax.swing.JToolBar.Separator separator2;
private javax.swing.JScrollPane tableScrollPane;
// End of variables declaration//GEN-END:variables
/**
* Gets default instance. Do not use directly: reserved for *.settings files only,
* i.e. deserialization routines; otherwise you could get a non-deserialized instance.
* To obtain the singleton instance, use {@link #findInstance}.
*/
public static synchronized DataTableTopComponent getDefault() {
if (instance == null) {
instance = new DataTableTopComponent();
}
return instance;
}
/**
* Obtain the DataTableTopComponent instance. Never call {@link #getDefault} directly!
*/
public static synchronized DataTableTopComponent findInstance() {
TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
if (win == null) {
Logger.getLogger(DataTableTopComponent.class.getName()).warning(
"Cannot find " + PREFERRED_ID + " component. It will not be located properly in the window system.");
return getDefault();
}
if (win instanceof DataTableTopComponent) {
return (DataTableTopComponent) win;
}
Logger.getLogger(DataTableTopComponent.class.getName()).warning(
"There seem to be multiple components with the '" + PREFERRED_ID
+ "' ID. That is a potential source of errors and unexpected behavior.");
return getDefault();
}
@Override
public int getPersistenceType() {
return TopComponent.PERSISTENCE_ALWAYS;
}
@Override
public void componentOpened() {
refreshAllOnce();
}
@Override
public void componentClosed() {
}
@Override
protected void componentActivated() {
super.componentActivated();
java.awt.Toolkit.getDefaultToolkit().addAWTEventListener(this, AWTEvent.KEY_EVENT_MASK);
}
@Override
protected void componentDeactivated() {
super.componentDeactivated();
java.awt.Toolkit.getDefaultToolkit().removeAWTEventListener(this);
}
/** replaces this in object stream */
@Override
public Object writeReplace() {
return new ResolvableHelper();
}
@Override
protected String preferredID() {
return PREFERRED_ID;
}
final static class ResolvableHelper implements Serializable {
private static final long serialVersionUID = 1L;
public Object readResolve() {
return DataTableTopComponent.getDefault();
}
}
/**
* <p>Exports a JTable to a CSV file showing first a dialog to select the file to write.</p>
* @param parent Parent window
* @param table Table to export
* @param separator Separator to use for separating values of a row in the CSV file. If null ',' will be used.
* @param charset Charset encoding for the file
* @param columnsToExport Indicates the indexes of the columns to export. All columns will be exported if null
*/
public static void exportTableAsCSV(JComponent parent, JTable table, Character separator, Charset charset, Integer[] columnsToExport) {
String lastPath = NbPreferences.forModule(TableCSVExporter.class).get(LAST_PATH, null);
final JFileChooser chooser = new JFileChooser(lastPath);
chooser.setAcceptAllFileFilterUsed(false);
DialogFileFilter dialogFileFilter = new DialogFileFilter(NbBundle.getMessage(TableCSVExporter.class, "TableCSVExporter.filechooser.csvDescription"));
dialogFileFilter.addExtension("csv");
chooser.addChoosableFileFilter(dialogFileFilter);
File selectedFile = new File(chooser.getCurrentDirectory(), "table.csv");
chooser.setSelectedFile(selectedFile);
int returnFile = chooser.showSaveDialog(null);
if (returnFile != JFileChooser.APPROVE_OPTION) {
return;
}
File file = chooser.getSelectedFile();
if (!file.getPath().endsWith(".csv")) {
file = new File(file.getPath() + ".csv");
}
//Save last path
String defaultDirectory = file.getParentFile().getAbsolutePath();
NbPreferences.forModule(TableCSVExporter.class).put(LAST_PATH, defaultDirectory);
try {
TableCSVExporter.writeCSVFile(table, file, separator, charset, columnsToExport);
JOptionPane.showMessageDialog(parent, NbBundle.getMessage(TableCSVExporter.class, "TableCSVExporter.dialog.success"));
} catch (IOException ex) {
JOptionPane.showMessageDialog(parent, NbBundle.getMessage(TableCSVExporter.class, "TableCSVExporter.dialog.error"), NbBundle.getMessage(TableCSVExporter.class, "TableCSVExporter.dialog.error.title"), JOptionPane.ERROR_MESSAGE);
}
}
private static final String LAST_PATH = "TableCSVExporter_Save_Last_Path";
}