Search in sources :

Example 16 with Column

use of au.gov.asd.tac.constellation.views.tableview.api.Column in project constellation by constellation-app.

the class Table method createColumnIndexPart.

/**
 * For the specified element type (vertex or transaction), iterates through
 * that element types attributes in the graph and generates columns for each
 * one.
 * <p/>
 * The column name will be the attribute name prefixed by the passed
 * {@code attributeNamePrefix} parameter. This parameter will be one of
 * "source.", "destination." or "transaction.".
 * <p/>
 * The column reference map contains previously generated columns and is
 * used as a reference so that new column objects are not created
 * needlessly.
 *
 * @param readableGraph the graph to extract the attributes from
 * @param elementType the type of elements that the attributes will be
 * extracted from, {@link GraphElementType#VERTEX} or
 * {@link GraphElementType#TRANSACTION}
 * @param attributeNamePrefix the string that will prefix the attribute name
 * in the column name, will be one of "source.", "destination." or
 * "transaction."
 * @param columnReferenceMap a map of existing columns that can be used
 * instead of creating new ones if the column names match up
 */
protected List<Column> createColumnIndexPart(final ReadableGraph readableGraph, final GraphElementType elementType, final String attributeNamePrefix, final Map<String, TableColumn<ObservableList<String>, String>> columnReferenceMap) {
    final List<Column> tmpColumnIndex = new CopyOnWriteArrayList<>();
    final int attributeCount = readableGraph.getAttributeCount(elementType);
    IntStream.range(0, attributeCount).forEach(attributePosition -> {
        final int attributeId = readableGraph.getAttribute(elementType, attributePosition);
        final String attributeName = attributeNamePrefix + readableGraph.getAttributeName(attributeId);
        final TableColumn<ObservableList<String>, String> column = columnReferenceMap.containsKey(attributeName) ? columnReferenceMap.get(attributeName) : createColumn(attributeName);
        tmpColumnIndex.add(new Column(attributeNamePrefix, new GraphAttribute(readableGraph, attributeId), column));
    });
    return tmpColumnIndex;
}
Also used : TableColumn(javafx.scene.control.TableColumn) Column(au.gov.asd.tac.constellation.views.tableview.api.Column) ObservableList(javafx.collections.ObservableList) GraphAttribute(au.gov.asd.tac.constellation.graph.GraphAttribute) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList)

Example 17 with Column

use of au.gov.asd.tac.constellation.views.tableview.api.Column in project constellation by constellation-app.

the class Table method updateColumns.

/**
 * Update the columns in the table using the graph and state. This will
 * clear and refresh the column index and then trigger a refresh of the
 * table view, populating from the new column index.
 * <p/>
 * If the table's state has an element type of VERTEX then all the columns
 * will be prefixed with ".source".
 * <p/>
 * If the element type is TRANSACTION then the attributes belonging to
 * transactions will be prefixed with ".transaction". The vertex attributes
 * will also be added as columns in this case. When the state's element type
 * is TRANSACTION the vertex attributes will be prefixed with both ".source"
 * and ".destination" so that it is distinguishable on which end of the
 * transaction those values are present.
 * <p/>
 * Note that column references are reused where possible to ensure certain
 * toolbar/menu operations to work correctly.
 * <p/>
 * The entire method is synchronized so it should be thread safe and keeps
 * the locking logic simpler. Maybe this method could be broken out further.
 *
 * @param graph the graph to retrieve data from.
 * @param state the current table view state.
 */
public void updateColumns(final Graph graph, final TableViewState state) {
    synchronized (TABLE_LOCK) {
        if (graph != null && state != null) {
            if (Platform.isFxApplicationThread()) {
                throw new IllegalStateException(ATTEMPT_PROCESS_JAVAFX);
            }
            if (SwingUtilities.isEventDispatchThread()) {
                throw new IllegalStateException(ATTEMPT_PROCESS_EDT);
            }
            // Clear current columnIndex, but cache the column objects for reuse
            final Map<String, TableColumn<ObservableList<String>, String>> columnReferenceMap = getColumnIndex().stream().collect(Collectors.toMap(column -> column.getTableColumn().getText(), column -> column.getTableColumn(), (e1, e2) -> e1));
            getColumnIndex().clear();
            // Update columnIndex based on graph attributes
            final ReadableGraph readableGraph = graph.getReadableGraph();
            try {
                // Creates "source." columns from vertex attributes
                getColumnIndex().addAll(createColumnIndexPart(readableGraph, GraphElementType.VERTEX, GraphRecordStoreUtilities.SOURCE, columnReferenceMap));
                if (state.getElementType() == GraphElementType.TRANSACTION) {
                    // Creates "transaction." columns from transaction attributes
                    getColumnIndex().addAll(createColumnIndexPart(readableGraph, GraphElementType.TRANSACTION, GraphRecordStoreUtilities.TRANSACTION, columnReferenceMap));
                    // Creates "destination." columns from vertex attributes
                    getColumnIndex().addAll(createColumnIndexPart(readableGraph, GraphElementType.VERTEX, GraphRecordStoreUtilities.DESTINATION, columnReferenceMap));
                }
            } finally {
                readableGraph.release();
            }
            // If there are no visible columns specified, write the key columns to the state
            if (state.getColumnAttributes() == null) {
                openColumnVisibilityMenu();
                return;
            }
            // Sort columns in columnIndex by state, prefix and attribute name
            getColumnIndex().sort(new ColumnIndexSort(state));
            // Style and format columns in columnIndex
            getColumnIndex().forEach(columnTuple -> {
                final TableColumn<ObservableList<String>, String> column = columnTuple.getTableColumn();
                // assign cells to columns
                column.setCellValueFactory(cellData -> {
                    final int cellIndex = tableView.getColumns().indexOf(cellData.getTableColumn());
                    if (cellIndex < cellData.getValue().size()) {
                        return new SimpleStringProperty(cellData.getValue().get(cellIndex));
                    } else {
                        return null;
                    }
                });
                // Assign values and styles to cells
                column.setCellFactory(cellColumn -> new TableCellFactory(cellColumn, this));
            });
            // calculated column changes
            if (!Thread.currentThread().isInterrupted()) {
                // The update columns task holds state between executions. So we need to
                // reset some fields each time before it is run.
                updateColumnsTask.reset(columnReferenceMap, state);
                Platform.runLater(updateColumnsTask);
            }
        }
    }
}
Also used : TableCellFactory(au.gov.asd.tac.constellation.views.tableview.factory.TableCellFactory) IntStream(java.util.stream.IntStream) ReadOnlyObjectProperty(javafx.beans.property.ReadOnlyObjectProperty) ReadableGraph(au.gov.asd.tac.constellation.graph.ReadableGraph) SimpleStringProperty(javafx.beans.property.SimpleStringProperty) FXCollections(javafx.collections.FXCollections) ColumnIndexSort(au.gov.asd.tac.constellation.views.tableview.utilities.ColumnIndexSort) ActiveTableReference(au.gov.asd.tac.constellation.views.tableview.api.ActiveTableReference) VisualConcept(au.gov.asd.tac.constellation.graph.schema.visual.concept.VisualConcept) ArrayList(java.util.ArrayList) Level(java.util.logging.Level) TableColumn(javafx.scene.control.TableColumn) Graph(au.gov.asd.tac.constellation.graph.Graph) SwingUtilities(javax.swing.SwingUtilities) Column(au.gov.asd.tac.constellation.views.tableview.api.Column) Insets(javafx.geometry.Insets) TableViewState(au.gov.asd.tac.constellation.views.tableview.state.TableViewState) ListChangeListener(javafx.collections.ListChangeListener) Pair(org.apache.commons.lang3.tuple.Pair) UpdateDataTask(au.gov.asd.tac.constellation.views.tableview.tasks.UpdateDataTask) AbstractAttributeInteraction(au.gov.asd.tac.constellation.graph.attribute.interaction.AbstractAttributeInteraction) Map(java.util.Map) TableView(javafx.scene.control.TableView) GraphAttribute(au.gov.asd.tac.constellation.graph.GraphAttribute) TablePane(au.gov.asd.tac.constellation.views.tableview.panes.TablePane) MenuItem(javafx.scene.control.MenuItem) GraphElementType(au.gov.asd.tac.constellation.graph.GraphElementType) SelectedOnlySelectionListener(au.gov.asd.tac.constellation.views.tableview.listeners.SelectedOnlySelectionListener) GraphRecordStoreUtilities(au.gov.asd.tac.constellation.graph.processing.GraphRecordStoreUtilities) Logger(java.util.logging.Logger) ImmutableObjectCache(au.gov.asd.tac.constellation.utilities.datastructure.ImmutableObjectCache) Collectors(java.util.stream.Collectors) Platform(javafx.application.Platform) List(java.util.List) SelectionMode(javafx.scene.control.SelectionMode) UpdateColumnsTask(au.gov.asd.tac.constellation.views.tableview.tasks.UpdateColumnsTask) TableSelectionListener(au.gov.asd.tac.constellation.views.tableview.listeners.TableSelectionListener) TABLE_LOCK(au.gov.asd.tac.constellation.views.tableview.TableViewTopComponent.TABLE_LOCK) TableViewUtilities(au.gov.asd.tac.constellation.views.tableview.utilities.TableViewUtilities) ObservableList(javafx.collections.ObservableList) ChangeListener(javafx.beans.value.ChangeListener) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) TableCellFactory(au.gov.asd.tac.constellation.views.tableview.factory.TableCellFactory) ReadableGraph(au.gov.asd.tac.constellation.graph.ReadableGraph) ObservableList(javafx.collections.ObservableList) ColumnIndexSort(au.gov.asd.tac.constellation.views.tableview.utilities.ColumnIndexSort) SimpleStringProperty(javafx.beans.property.SimpleStringProperty) TableColumn(javafx.scene.control.TableColumn)

Example 18 with Column

use of au.gov.asd.tac.constellation.views.tableview.api.Column in project constellation by constellation-app.

the class PreferencesMenu method loadPreferences.

/**
 * Loads a saved table preferences JSON file and updates the table format
 * (displayed column/column order and sort order) to match the values found.
 * <p/>
 * This method will place a lock on the table to prevent any updates to the
 * preferences whilst this load is happening.
 * <p/>
 * This method will start work on the JavaFX thread to update certain parts
 * of the table like column visibility. Once the method returns it is
 * recommended that the current thread waits for that work to complete
 * before initiating any other actions.
 */
protected void loadPreferences() {
    synchronized (TABLE_LOCK) {
        if (getTableViewTopComponent().getCurrentState() != null) {
            // Load the local table preferences JSON file
            final UserTablePreferences tablePrefs = TableViewPreferencesIoProvider.getPreferences(getTableViewTopComponent().getCurrentState().getElementType());
            // cannot occur with 0 columns
            if (tablePrefs == null || CollectionUtils.isEmpty(tablePrefs.getColumnOrder())) {
                return;
            }
            final List<TableColumn<ObservableList<String>, ?>> newColumnOrder = new ArrayList<>();
            // Loop through column names in the loaded preferences and add the
            // associated columns to newColumnOrder (if found). Also set the
            // found columns to visible.
            tablePrefs.getColumnOrder().forEach(columnName -> getTable().getTableView().getColumns().stream().filter(column -> column.getText().equals(columnName)).forEachOrdered(column -> {
                column.setVisible(true);
                newColumnOrder.add(column);
            }));
            // Populate orderedColumns with entries from column index that match
            // the names of the columns in the loaded preferences.
            final List<Tuple<String, Attribute>> orderedColumns = newColumnOrder.stream().map(tableColumn -> {
                for (final Column column : getTable().getColumnIndex()) {
                    if (tableColumn.getText().equals(column.getTableColumn().getText())) {
                        return column;
                    }
                }
                // column specified in the preferences
                return null;
            }).filter(Objects::nonNull).map(column -> Tuple.create(column.getAttributeNamePrefix(), column.getAttribute())).collect(Collectors.toList());
            // Update the sort preferences
            getActiveTableReference().saveSortDetails(tablePrefs.getSortColumn(), tablePrefs.getSortDirection());
            try {
                // Update the visibile columns and wait for the state plugin to complete its update
                getActiveTableReference().updateVisibleColumns(getTableViewTopComponent().getCurrentGraph(), getTableViewTopComponent().getCurrentState(), orderedColumns, UpdateMethod.REPLACE).get(1000, TimeUnit.MILLISECONDS);
            } catch (final InterruptedException ex) {
                LOGGER.log(Level.WARNING, "Update state plugin was interrupted");
                Thread.currentThread().interrupt();
            } catch (final TimeoutException | ExecutionException ex) {
                LOGGER.log(Level.WARNING, "Update state plugin failed to complete within the alloted time", ex);
            }
            // Update the page size menu selection and page size preferences
            for (final Toggle t : getPageSizeToggle().getToggles()) {
                final RadioMenuItem pageSizeOption = (RadioMenuItem) t;
                if (Integer.parseInt(pageSizeOption.getText()) == tablePrefs.getMaxRowsPerPage()) {
                    pageSizeOption.setSelected(true);
                    getActiveTableReference().getUserTablePreferences().setMaxRowsPerPage(tablePrefs.getMaxRowsPerPage());
                    break;
                }
            }
        }
    }
}
Also used : IntStream(java.util.stream.IntStream) EventHandler(javafx.event.EventHandler) RadioMenuItem(javafx.scene.control.RadioMenuItem) Tuple(au.gov.asd.tac.constellation.utilities.datastructure.Tuple) UpdateMethod(au.gov.asd.tac.constellation.views.tableview.api.UpdateMethod) TimeoutException(java.util.concurrent.TimeoutException) ActiveTableReference(au.gov.asd.tac.constellation.views.tableview.api.ActiveTableReference) TableViewPreferencesIoProvider(au.gov.asd.tac.constellation.views.tableview.io.TableViewPreferencesIoProvider) Side(javafx.geometry.Side) CollectionUtils(org.apache.commons.collections4.CollectionUtils) ArrayList(java.util.ArrayList) Level(java.util.logging.Level) TableColumn(javafx.scene.control.TableColumn) Column(au.gov.asd.tac.constellation.views.tableview.api.Column) UserTablePreferences(au.gov.asd.tac.constellation.views.tableview.api.UserTablePreferences) Attribute(au.gov.asd.tac.constellation.graph.Attribute) UserInterfaceIconProvider(au.gov.asd.tac.constellation.utilities.icon.UserInterfaceIconProvider) GraphManager(au.gov.asd.tac.constellation.graph.manager.GraphManager) TableViewTopComponent(au.gov.asd.tac.constellation.views.tableview.TableViewTopComponent) TablePane(au.gov.asd.tac.constellation.views.tableview.panes.TablePane) MenuItem(javafx.scene.control.MenuItem) Logger(java.util.logging.Logger) Collectors(java.util.stream.Collectors) Menu(javafx.scene.control.Menu) Objects(java.util.Objects) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) ActionEvent(javafx.event.ActionEvent) ToggleGroup(javafx.scene.control.ToggleGroup) ImageView(javafx.scene.image.ImageView) MenuButton(javafx.scene.control.MenuButton) TABLE_LOCK(au.gov.asd.tac.constellation.views.tableview.TableViewTopComponent.TABLE_LOCK) Toggle(javafx.scene.control.Toggle) ObservableList(javafx.collections.ObservableList) ArrayList(java.util.ArrayList) RadioMenuItem(javafx.scene.control.RadioMenuItem) TableColumn(javafx.scene.control.TableColumn) UserTablePreferences(au.gov.asd.tac.constellation.views.tableview.api.UserTablePreferences) TableColumn(javafx.scene.control.TableColumn) Column(au.gov.asd.tac.constellation.views.tableview.api.Column) Toggle(javafx.scene.control.Toggle) Objects(java.util.Objects) ExecutionException(java.util.concurrent.ExecutionException) Tuple(au.gov.asd.tac.constellation.utilities.datastructure.Tuple) TimeoutException(java.util.concurrent.TimeoutException)

Aggregations

Column (au.gov.asd.tac.constellation.views.tableview.api.Column)18 TableColumn (javafx.scene.control.TableColumn)17 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)13 ObservableList (javafx.collections.ObservableList)11 Test (org.testng.annotations.Test)11 Attribute (au.gov.asd.tac.constellation.graph.Attribute)9 GraphAttribute (au.gov.asd.tac.constellation.graph.GraphAttribute)9 ReadableGraph (au.gov.asd.tac.constellation.graph.ReadableGraph)8 ActiveTableReference (au.gov.asd.tac.constellation.views.tableview.api.ActiveTableReference)5 TableViewState (au.gov.asd.tac.constellation.views.tableview.state.TableViewState)5 TableViewTopComponent (au.gov.asd.tac.constellation.views.tableview.TableViewTopComponent)4 TablePane (au.gov.asd.tac.constellation.views.tableview.panes.TablePane)4 List (java.util.List)4 ListChangeListener (javafx.collections.ListChangeListener)4 CustomMenuItem (javafx.scene.control.CustomMenuItem)4 Graph (au.gov.asd.tac.constellation.graph.Graph)3 UpdateColumnsTask (au.gov.asd.tac.constellation.views.tableview.tasks.UpdateColumnsTask)3 ArrayList (java.util.ArrayList)3 Collectors (java.util.stream.Collectors)3 Platform (javafx.application.Platform)3