use of au.gov.asd.tac.constellation.views.tableview.TableViewTopComponent.TABLE_LOCK 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);
}
}
}
}
use of au.gov.asd.tac.constellation.views.tableview.TableViewTopComponent.TABLE_LOCK 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;
}
}
}
}
}
Aggregations