use of CCDD.CcddClassesDataTable.FieldInformation in project CCDD by nasa.
the class CcddFieldTableEditorDialog method getDataFieldsToDisplay.
/**
********************************************************************************************
* Build the data field array
*
* @return Array containing the data field owner names and corresponding user-selected data
* field values
********************************************************************************************
*/
private Object[][] getDataFieldsToDisplay() {
isPath = false;
List<Object[]> ownerDataFields = new ArrayList<Object[]>();
List<String[]> ownersInTable = new ArrayList<String[]>();
// Get the list of selected tables
List<String> filterTables = tableTree.getSelectedTablesWithChildren();
// Add the ancestors of the selected tables to the list of filter tables
tableTree.addTableAncestors(filterTables, false);
// Create a field handler and populate it with the field definitions for all of the tables
// and groups in the database
fieldHandler = new CcddFieldHandler(ccddMain);
fieldHandler.buildFieldInformation(dataFields.toArray(new String[0][0]), null);
List<FieldInformation> fieldInformation = fieldHandler.getFieldInformation();
// Sort the field information by owner name so that sequence order of the data field values
// is based on the owners' alphabetical order
Collections.sort(fieldInformation, new Comparator<FieldInformation>() {
/**
************************************************************************************
* Compare the owner names of two field definitions. Force lower case to eliminate case
* differences in the comparison
************************************************************************************
*/
@Override
public int compare(FieldInformation fld1, FieldInformation fld2) {
return fld1.getOwnerName().toLowerCase().compareTo(fld2.getOwnerName().toLowerCase());
}
});
// Step through each defined data field
for (int index = 0; index < fieldInformation.size(); index++) {
// Get the reference to the field information
FieldInformation fieldInfo = fieldInformation.get(index);
// Get the data field owner's name
String ownerName = fieldInfo.getOwnerName();
// all tables are considered to match)
if (filterTables.isEmpty() || filterTables.contains(ownerName)) {
String pathName = "";
// Get the index of the last comma in the field table path & name
int commaIndex = ownerName.lastIndexOf(",");
// Check if a comma was found in the table path & name
if (commaIndex != -1) {
// Extract the path name from the table path and name
pathName = ownerName.substring(0, commaIndex);
// Count the number of commas in the path name, which indicates the structure
// nest level
int depth = pathName.split(",").length;
// Set the indentation
String indent = "";
// Step through each nest level
for (int count = 0; count < depth; count++) {
// Add spaces to the indentation. This aids in identifying the structure
// members
indent += " ";
}
// Remove the path and leave only the table name
ownerName = indent + ownerName.substring(commaIndex + 1);
// Add spaces after any remaining commas in the path
pathName = pathName.replaceAll(",", ", ");
}
int dataFieldIndex = -1;
// Step through each column
for (int fieldIndex = 0; fieldIndex < columnNames.length; fieldIndex++) {
// Check if the column name matches the data field name
if (fieldInfo.getFieldName().equals(columnNames[fieldIndex])) {
// Set the index to the matching data field column
dataFieldIndex = fieldIndex;
// added to the list
if (fieldInfo.getInputType().getInputFormat() == InputTypeFormat.BOOLEAN && !checkBoxColumns.contains(fieldIndex)) {
// Store the column index in the check box column list
checkBoxColumns.add(fieldIndex);
}
break;
}
}
// Check if a target data field is present
if (dataFieldIndex != -1) {
boolean isFound = false;
int row = 0;
// Step through the owners added to this point
for (String[] inTable : ownersInTable) {
// Check if the owner name and path for the data field matches
if (ownerName.equals(inTable[0]) && pathName.equals(inTable[1])) {
// Store the data field value in the existing list item and stop
// searching
ownerDataFields.get(row)[dataFieldIndex] = fieldInfo.getInputType().getInputFormat() == InputTypeFormat.BOOLEAN ? Boolean.valueOf(fieldInfo.getValue()) : fieldInfo.getValue();
isFound = true;
break;
}
row++;
}
// Check if the owner isn't already in the list
if (!isFound) {
// Add the non-highlighted owner and path names to the list of owners
// already added to the table
ownersInTable.add(new String[] { ownerName, pathName });
// Create a new row for the owner
Object[] newTable = new Object[columnNames.length];
Arrays.fill(newTable, "");
// Check if the field owner isn't a table
if (ownerIsNotTable(ownerName)) {
// Highlight the field owner indicator
newTable[FieldTableEditorColumnInfo.OWNER.ordinal()] = highlightFieldOwner(ownerName, true);
} else // The field belongs to a data table
{
// Highlight the data type(s) in the table
newTable[FieldTableEditorColumnInfo.OWNER.ordinal()] = CcddUtilities.highlightDataType(ownerName);
}
// Insert the owner name, path, and the data field value into the new row
newTable[FieldTableEditorColumnInfo.PATH.ordinal()] = CcddUtilities.highlightDataType(pathName);
newTable[dataFieldIndex] = fieldInfo.getInputType().getInputFormat() == InputTypeFormat.BOOLEAN ? Boolean.valueOf(fieldInfo.getValue()) : fieldInfo.getValue();
// Add the field row to the list
ownerDataFields.add(newTable);
// Check if this owner has a path (i.e., it's a structure table)
if (!pathName.isEmpty()) {
// Set the flag to indicate at least one of the owners has a path
isPath = true;
}
}
}
}
}
// any that have a blank value can be set to false (a legal boolean value)
for (int cbxCol : checkBoxColumns) {
// Set through each row in the table
for (Object[] ownerDataField : ownerDataFields) {
// Check if the check box value is blank
if (ownerDataField[cbxCol] == "") {
// Set the check box value to false
ownerDataField[cbxCol] = false;
}
}
}
return ownerDataFields.toArray(new Object[0][0]);
}
use of CCDD.CcddClassesDataTable.FieldInformation in project CCDD by nasa.
the class CcddFieldTableEditorDialog method createDataFieldTableEditorTable.
/**
********************************************************************************************
* Create the data field table editor table
*
* @return Reference to the scroll pane in which the table is placed
********************************************************************************************
*/
private JScrollPane createDataFieldTableEditorTable() {
// Create the table to display the structure tables and their corresponding user-selected
// data fields
dataFieldTable = new CcddJTableHandler() {
/**
************************************************************************************
* Allow resizing of the any column unless it displays a check box
************************************************************************************
*/
@Override
protected boolean isColumnResizable(int column) {
return !checkBoxColumns.contains(column);
}
/**
************************************************************************************
* Allow multiple line display in all columns except those displaying check boxes
************************************************************************************
*/
@Override
protected boolean isColumnMultiLine(int column) {
return !checkBoxColumns.contains(column);
}
/**
************************************************************************************
* Allow HTML-formatted text in the specified column(s)
************************************************************************************
*/
@Override
protected boolean isColumnHTML(int column) {
return column == FieldTableEditorColumnInfo.OWNER.ordinal() || column == FieldTableEditorColumnInfo.PATH.ordinal();
}
/**
************************************************************************************
* Hide the specified column(s)
************************************************************************************
*/
@Override
protected boolean isColumnHidden(int column) {
return !isPath && column == FieldTableEditorColumnInfo.PATH.ordinal();
}
/**
************************************************************************************
* Display the specified column(s) as check boxes
************************************************************************************
*/
@Override
protected boolean isColumnBoolean(int column) {
return checkBoxColumns.contains(column);
}
/**
************************************************************************************
* Allow editing of the table cells in the specified columns only
************************************************************************************
*/
@Override
public boolean isCellEditable(int row, int column) {
// Convert the coordinates from view to model
row = convertRowIndexToModel(row);
column = convertColumnIndexToModel(column);
// have the field specified by the column
return column != FieldTableEditorColumnInfo.OWNER.ordinal() && column != FieldTableEditorColumnInfo.PATH.ordinal() && fieldHandler.getFieldInformationByName(getOwnerWithPath(getModel().getValueAt(row, FieldTableEditorColumnInfo.OWNER.ordinal()).toString(), getModel().getValueAt(row, FieldTableEditorColumnInfo.PATH.ordinal()).toString()), columnNames[column]) != null;
}
/**
************************************************************************************
* Allow pasting data into the data field cells
************************************************************************************
*/
@Override
protected boolean isDataAlterable(Object[] rowData, int row, int column) {
return isCellEditable(convertRowIndexToView(row), convertColumnIndexToView(column));
}
/**
************************************************************************************
* Validate changes to the data field value cells; e.g., verify cell content and, if
* found invalid, revert to the original value
*
* @param tableData
* list containing the table data row arrays
*
* @param row
* table model row number
*
* @param column
* table model column number
*
* @param oldValue
* original cell contents
*
* @param newValue
* new cell contents
*
* @param showMessage
* unused
*
* @param isMultiple
* unused
*
* @return Value of ShowMessage
***********************************************************************************
*/
@Override
protected Boolean validateCellContent(List<Object[]> tableData, int row, int column, Object oldValue, Object newValue, Boolean showMessage, boolean isMultiple) {
// Reset the flag that indicates the last edited cell's content is invalid
setLastCellValid(true);
// Create a string version of the new value
String newValueS = newValue.toString();
// Check that the new cell value isn't blank
if (!newValueS.isEmpty()) {
// Get the owner name, with path if applicable
String ownerAndPath = getOwnerWithPath(tableData.get(row)[FieldTableEditorColumnInfo.OWNER.ordinal()].toString(), tableData.get(row)[FieldTableEditorColumnInfo.PATH.ordinal()].toString());
// Get the reference to the data field
FieldInformation fieldInfo = fieldHandler.getFieldInformationByName(ownerAndPath, columnNames[column]);
// Check that the data field was found
if (fieldInfo != null) {
// this data field
if (fieldInfo.getInputType().getInputMatch().isEmpty() || newValueS.matches(fieldInfo.getInputType().getInputMatch())) {
// Store the new value in the table data array after formatting the
// cell value per its input type. This is needed primarily to clean up
// numeric formatting
newValueS = fieldInfo.getInputType().formatInput(newValueS);
tableData.get(row)[column] = newValueS;
} else // The value doesn't match the pattern for this data field
{
// Set the flag that indicates the last edited cell's content is
// invalid
setLastCellValid(false);
// Inform the user that the data field contents is invalid
new CcddDialogHandler().showMessageDialog(CcddFieldTableEditorDialog.this, "<html><b>Invalid characters in field '</b>" + fieldInfo.getFieldName() + "<b>'; " + fieldInfo.getInputType().getInputName().toLowerCase() + " expected", "Invalid " + fieldInfo.getInputType().getInputName(), JOptionPane.WARNING_MESSAGE, DialogOption.OK_OPTION);
// Restore the cell contents to its original value
tableData.get(row)[column] = oldValue;
getUndoManager().undoRemoveEdit();
}
}
}
return showMessage;
}
/**
************************************************************************************
* Load the data field data into the table and format the table cells
************************************************************************************
*/
@Override
protected void loadAndFormatData() {
// Get the default column names and tool tip text for the data field editor table
String[] toolTips = new String[columnNames.length];
toolTips[FieldTableEditorColumnInfo.OWNER.ordinal()] = FieldTableEditorColumnInfo.OWNER.getToolTip();
toolTips[FieldTableEditorColumnInfo.PATH.ordinal()] = FieldTableEditorColumnInfo.PATH.getToolTip();
// Create lists for any columns to be displayed as check boxes
checkBoxColumns = new ArrayList<Integer>();
// Get the owners, paths, data field values values, and check box columns based on
// the specified data fields
committedData = getDataFieldsToDisplay();
// Place the data into the table model along with the column names, set up the
// editors and renderers for the table cells, set up the table grid lines, and
// calculate the minimum width required to display the table information
setUpdatableCharacteristics(committedData, columnNames, null, toolTips, true, true, true);
}
/**
************************************************************************************
* Override the CcddJTableHandler method in order to show/hide the data fields based on
* the selected field filters
************************************************************************************
*/
@Override
protected void setTableSortable() {
super.setTableSortable();
// Get the table's row sorter and add the event type filter
TableRowSorter<?> sorter = (TableRowSorter<?>) getRowSorter();
// filter hasn't been set, and that there is a field owner row filter
if (sorter != null && sorter.getRowFilter() != rowFilter && rowFilter != null) {
// Apply the row filter that shows/hides the event types
sorter.setRowFilter(rowFilter);
}
}
/**
************************************************************************************
* Override prepareRenderer to allow adjusting the background colors of table cells
************************************************************************************
*/
@Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
JComponent comp = (JComponent) super.prepareRenderer(renderer, row, column);
// Get the column index in model coordinates
int columnModel = convertColumnIndexToModel(column);
// highlight colors override the invalid highlight color
if (comp.getBackground() != ModifiableColorInfo.FOCUS_BACK.getColor() && comp.getBackground() != ModifiableColorInfo.SELECTED_BACK.getColor() && columnModel != FieldTableEditorColumnInfo.OWNER.ordinal()) {
// Get the row index in model coordinates
int rowModel = convertRowIndexToModel(row);
// Get a reference to the table model to shorten subsequent calls
TableModel tableModel = getModel();
// Get the contents of the owner and path columns
String ownerName = tableModel.getValueAt(rowModel, FieldTableEditorColumnInfo.OWNER.ordinal()).toString();
String pathValue = tableModel.getValueAt(rowModel, FieldTableEditorColumnInfo.PATH.ordinal()).toString();
// Get the owner, including the path (if a child structure table), with any
// highlighting removed (this is the field owner as stored in the project's
// data field table)
String ownerPath = getOwnerWithPath(ownerName, pathValue);
// Check if this is the structure path column
if (columnModel == FieldTableEditorColumnInfo.PATH.ordinal()) {
// Check if the cell is blank and that the owner is a structure table
if (pathValue.isEmpty() && (nonStructureTableNames.contains(ownerPath) || ownerIsNotTable(ownerName))) {
// Set the cell's background color to indicate the structure path isn't
// applicable for this table
comp.setBackground(ModifiableColorInfo.PROTECTED_BACK.getColor());
}
} else // Check if this table has the data field identified by the column
if (fieldHandler.getFieldInformationByName(ownerPath, columnNames[columnModel]) != null) {
// Check if the cell is a data field selected for removal
if (selectedCells.contains(row, column)) {
// Change the cell's colors to indicate the data field represented by
// the cell is selected for removal
comp.setForeground(Color.GRAY);
comp.setBackground(Color.RED);
} else // a boolean value (these are not compared for duplicate values)
if (!checkBoxColumns.contains(columnModel)) {
// Get the input data type for this data field
InputDataType inputType = fieldHandler.getFieldInformationByName(ownerPath, columnNames[columnModel]).getInputType();
// Get the text in the cell, formatted per its input type, but without
// preserving the leading zeroes for hexadecimal values
String value = inputType.formatInput(tableModel.getValueAt(rowModel, columnModel).toString(), false);
// Step through each row in the table
for (int checkRow = 0; checkRow < tableModel.getRowCount(); checkRow++) {
// row of the same column
if (rowModel != checkRow && !value.isEmpty() && inputType.formatInput(tableModel.getValueAt(checkRow, columnModel).toString(), false).equals(value)) {
// Change the cell's background color to indicate it has the
// same value as another cell in the same column
comp.setBackground(ModifiableColorInfo.REQUIRED_BACK.getColor());
break;
}
}
}
} else // The table indicated by this row does not have a data field as identified by
// the column
{
// Set the cell's background color to indicate the data field doesn't exist
// for this table
comp.setBackground(ModifiableColorInfo.PROTECTED_BACK.getColor());
}
}
return comp;
}
/**
************************************************************************************
* Handle a change to the table's content
************************************************************************************
*/
@Override
protected void processTableContentChange() {
// Add or remove the change indicator based on whether any unstored changes exist
setTitle(DIALOG_TITLE + (isFieldTableChanged() ? "*" : ""));
// Force the table to redraw so that changes to the cells are displayed
repaint();
}
};
// Place the table into a scroll pane
JScrollPane scrollPane = new JScrollPane(dataFieldTable);
// Disable storage of edit operations during table creation
dataFieldTable.getUndoHandler().setAllowUndo(false);
// Set up the field table parameters
dataFieldTable.setFixedCharacteristics(scrollPane, false, ListSelectionModel.MULTIPLE_INTERVAL_SELECTION, TableSelectionMode.SELECT_BY_CELL, true, ModifiableColorInfo.TABLE_BACK.getColor(), true, true, ModifiableFontInfo.OTHER_TABLE_CELL.getFont(), true);
// Set the reference to the cell selection container in the undo handler, then create a
// cell selection object
dataFieldTable.getUndoHandler().setSelectedCells(selectedCells);
cellSelect = dataFieldTable.getUndoHandler().new UndoableCellSelection();
// Re-enable storage of edit operations
dataFieldTable.getUndoHandler().setAllowUndo(true);
return scrollPane;
}
use of CCDD.CcddClassesDataTable.FieldInformation in project CCDD by nasa.
the class CcddTableEditorHandler method doTableUpdatesComplete.
/**
********************************************************************************************
* Perform the steps needed following execution of database table changes
*
* @param dbTableInfo
* table's information, as it currently exists in the database
*
* @param applyToChild
* true if the table that was updated is a prototype and this table is a child of
* the updated table
********************************************************************************************
*/
protected void doTableUpdatesComplete(TableInformation dbTableInfo, boolean applyToChild) {
Object[][] originalCommData = null;
Integer[] emptyRows = null;
// Check if this is the editor for the table that was changed
if (dbTableInfo.getTablePath().equals(tableInfo.getTablePath())) {
// Store the indices for any empty rows; the empty rows are restored after the table
// data is replaced
emptyRows = getEmptyRows();
// Replace any custom value deletion flags with blanks
clearCustomValueDeletionFlags();
}
// Check if a cell editor is active
if (table.getCellEditor() != null) {
// Terminate cell editing. If this is not done the cell with the active editor isn't
// updated
table.getCellEditor().stopCellEditing();
}
// Check if the table contains any committed data
if (committedInfo.getData().length != 0) {
originalCommData = new Object[committedInfo.getData().length][committedInfo.getData()[0].length];
// Step through the currently committed data rows
for (int row = 0; row < committedInfo.getData().length; row++) {
// Step through the currently committed data columns
for (int column = 0; column < committedInfo.getData()[row].length; column++) {
// Store the currently committed data cell value. Note that this is what this
// editor considers the committed data and doesn't reflect changes that were
// made externally (such as a change to a prototype altering an instance's
// contents)
originalCommData[row][column] = committedInfo.getData()[row][column];
}
}
}
// Load the committed array of data into the table
table.loadDataArrayIntoTable(dbTableInfo.getData(), false);
// Store the table information that represents the currently committed table data
setCommittedInformation(dbTableInfo);
// Check if this is the editor for the table that was changed
if (dbTableInfo.getTablePath().equals(tableInfo.getTablePath())) {
// Restore any empty rows
restoreEmptyRows(emptyRows);
}
// Get the variable path separators and (re)create the variable path column content, if
// present
updateVariablePaths();
// needs to have the same changes applied
if (applyToChild) {
// Store the current array member display status
boolean isShowArrayMembersOld = isShowArrayMembers;
// Check if array members are currently hidden
if (!isShowArrayMembers) {
// Display the array members. All rows must be displayed in order for any
// uncommitted changes to be re-applied since isCellEditable() (called below)
// requires the view coordinates
showHideArrayMembers();
}
// Get the table's currently displayed data
Object[][] preChangeData = table.getTableData(true);
// Disable automatic termination of edits so that all of the changes can be combined
// into a single edit
table.getUndoHandler().setAutoEndEditSequence(false);
// Step through each row of the table (committed)
for (int postRow = 0; postRow < tableModel.getRowCount(); postRow++) {
// Step through each row of the table (uncommitted)
for (int preRow = 0; preRow < preChangeData.length; preRow++) {
// Check if the rows are the same, based on the primary key value
if (tableModel.getValueAt(postRow, primaryKeyIndex).equals(preChangeData[preRow][primaryKeyIndex])) {
// Step though each column in the row
for (int column = 0; column < tableModel.getColumnCount(); column++) {
// Get the value of the cell prior to the change
String preChangeCell = preChangeData[preRow][column].toString();
// cell values
if (!tableModel.getValueAt(postRow, column).toString().equals(preChangeCell) && (originalCommData == null || !originalCommData[preRow][column].toString().equals(preChangeCell))) {
// Convert the row and column indices to view coordinates
int modelRow = table.convertRowIndexToView(postRow);
int modelColumn = table.convertColumnIndexToView(column);
// non-integer)
if (modelRow != -1 && modelColumn != -1 && table.isCellEditable(table.convertRowIndexToView(postRow), table.convertColumnIndexToView(column))) {
// Update the value in the cell
tableModel.setValueAt(preChangeCell, postRow, column);
}
}
}
break;
}
}
}
// Get the current table description
String description = getDescription();
// Check if the description doesn't match the one stored in the database
if (!description.equals(dbTableInfo.getDescription())) {
// Set the description so that when it is restored it's flagged as an undoable
// change
setDescription(dbTableInfo.getDescription());
updateDescriptionField(false);
// Restore the description, with the undo flag enabled
setDescription(description);
updateDescriptionField(true);
}
// Get the current table column order
String columnOrder = table.getColumnOrder();
// Check if the column order doesn't match the one stored in the database
if (!columnOrder.equals(dbTableInfo.getColumnOrder())) {
// Set the column order so that when it is restored it's flagged as an undoable
// change
table.getUndoHandler().setAllowUndo(false);
table.arrangeColumns(dbTableInfo.getColumnOrder());
// Restore the column order
table.getUndoHandler().setAllowUndo(true);
table.arrangeColumns(columnOrder);
}
// Check if the data fields don't match those stored in the database
if (CcddFieldHandler.isFieldChanged(getFieldHandler().getFieldInformation(), dbTableInfo.getFieldHandler().getFieldInformation(), false)) {
// Create a copy of the current data fields
List<FieldInformation> currentFields = getFieldHandler().getFieldInformationCopy();
// Set the data fields so that when these are restored it's flagged as an undoable
// change
getFieldHandler().setFieldInformation(dbTableInfo.getFieldHandler().getFieldInformation());
createDataFieldPanel(false);
storeCurrentFieldInformation();
// Restore the data fields
getFieldHandler().setFieldInformation(currentFields);
createDataFieldPanel(true);
storeCurrentFieldInformation();
}
// Enable automatic edit termination and end the edit sequence. Any uncommitted changes
// are now combined into a single edit that can be undone/redone
table.getUndoHandler().setAutoEndEditSequence(true);
table.getUndoManager().endEditSequence();
// Check if the array member visibility was changed above
if (isShowArrayMembersOld != isShowArrayMembers) {
// Restore the original array member visibility
showHideArrayMembers();
}
}
// Update the change indicator in the editor tab
updateOwnerChangeIndicator();
}
use of CCDD.CcddClassesDataTable.FieldInformation in project CCDD by nasa.
the class CcddGroupManagerDialog method renameGroup.
/**
********************************************************************************************
* Rename the selected group
********************************************************************************************
*/
private void renameGroup() {
// Get the selected group(s)
String[] selected = groupTree.getTopLevelSelectedNodeNames();
// Check that a single node is selected in the group tree
if (selected.length == 1) {
// Create a panel to contain the dialog components
JPanel dialogPnl = new JPanel(new GridBagLayout());
// Create the group renaming dialog label and field
addGroupNameField("Rename '" + selected[0] + "' to:", selected[0], dialogPnl);
// Create the group renaming dialog
CcddDialogHandler groupDlg = new CcddDialogHandler() {
/**
********************************************************************************
* Verify that the dialog content is valid
*
* @return true if the input values are valid
********************************************************************************
*/
@Override
protected boolean verifySelection() {
return verifyGroupName(this);
}
};
// Display the group renaming dialog
if (groupDlg.showOptionsDialog(groupMgr, dialogPnl, "Rename Group", DialogOption.RENAME_OPTION, true) == OK_BUTTON) {
// Disable automatically ending the edit sequence. This allows all of the renamed
// group's edits to be grouped into a single sequence so that if undone, the edits
// are restored together
undoHandler.setAutoEndEditSequence(false);
// Rename the group
groupHandler.getGroupInformationByName(selected[0]).setName(groupNameFld.getText());
groupTree.renameRootChildNode(selected[0], groupNameFld.getText());
// Add the original name to the list of deleted groups so that the group's data
// fields are removed from the internal data fields table
deletedGroups.add(selected[0]);
// Step through each data field in the renamed group
for (FieldInformation fieldInfo : groupHandler.getGroupInformationByName(groupNameFld.getText()).getFieldInformation()) {
// Set the data field owner to the renamed group's name so that the group's
// data fields will be created in the internal data fields table
fieldInfo.setOwnerName(CcddFieldHandler.getFieldGroupName(groupNameFld.getText()));
}
// Update the group dialog's change indicator
updateChangeIndicator();
// Re-enable automatic edit sequence ending, then end the edit sequence to group
// the renamed group's edits
undoHandler.setAutoEndEditSequence(true);
undoManager.endEditSequence();
}
}
}
use of CCDD.CcddClassesDataTable.FieldInformation in project CCDD by nasa.
the class CcddGroupManagerDialog method initialize.
/**
********************************************************************************************
* Create the group manager dialog. This is executed in a separate thread since it can take a
* noticeable amount time to complete, and by using a separate thread the GUI is allowed to
* continue to update. The GUI menu commands, however, are disabled until the telemetry
* scheduler initialization completes execution
********************************************************************************************
*/
private void initialize() {
// Build the group manager dialog in the background
CcddBackgroundCommand.executeInBackground(ccddMain, new BackgroundCommand() {
// Create panels to hold the components of the dialog
JPanel dialogPnl = new JPanel(new GridBagLayout());
JPanel buttonPnl = new JPanel();
JButton btnClose;
/**
************************************************************************************
* Build the group manager dialog
************************************************************************************
*/
@Override
protected void execute() {
isNodeSelectionChanging = false;
// Set the flag to indicate the group manager dialog is being initialized
isInitializing = true;
// Create borders for the dialog components
border = BorderFactory.createCompoundBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED, Color.LIGHT_GRAY, Color.GRAY), BorderFactory.createEmptyBorder(ModifiableSpacingInfo.INPUT_FIELD_PADDING.getSpacing(), ModifiableSpacingInfo.INPUT_FIELD_PADDING.getSpacing(), ModifiableSpacingInfo.INPUT_FIELD_PADDING.getSpacing(), ModifiableSpacingInfo.INPUT_FIELD_PADDING.getSpacing()));
emptyBorder = BorderFactory.createEmptyBorder();
// Set the initial layout manager characteristics
GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(ModifiableSpacingInfo.LABEL_VERTICAL_SPACING.getSpacing() / 2, ModifiableSpacingInfo.LABEL_HORIZONTAL_SPACING.getSpacing() / 2, 0, 0), 0, 0);
selectedGroup = null;
deletedGroups = new ArrayList<String>();
// Add an undo edit manager
undoManager = new CcddUndoManager() {
/**
****************************************************************************
* Update the change indicator if the editor panel has changed
****************************************************************************
*/
@Override
protected void ownerHasChanged() {
// during initialization are ignored
if (!isInitializing) {
updateChangeIndicator();
}
}
};
// Create the undo handler for the components with undoable actions. Disable
// storage of edit actions during dialog creation
undoHandler = new CcddUndoHandler(undoManager);
nodeSelect = undoHandler.new UndoableTreePathSelection();
undoHandler.setAllowUndo(false);
// Build the group tree
groupTree = new CcddGroupTreeHandler(ccddMain, undoHandler, ccddMain.getMainFrame()) {
/**
****************************************************************************
* Respond to changes in selection of a node in the group tree
****************************************************************************
*/
@Override
protected void updateTableSelection() {
// Check that a node selection change is not in progress
if (!isNodeSelectionChanging) {
// Set the flag to prevent link tree updates
isNodeSelectionChanging = true;
// Needed for the group manager dialog's size to be adjusted for the
// data fields
groupMgr.setPreferredSize(null);
// Store any changes to the currently selected group, if applicable
updateSelectedGroupInformation();
// Update the description field text so that it can be undone/redone.
// The focus change, which is usually used to perform the update,
// occurs after the node selection edit and would cause the wrong
// description field to be changed
fieldPnlHndlr.updateDescriptionField(true);
// Get the name of the selected group(s)
String[] selected = getTopLevelSelectedNodeNames();
// If a single group is selected then set the selected group, enable
// and populate the description field, and display the group's data
// fields; otherwise clear the selected group, disable and clear the
// description field, and remove any data fields
setGroupAndFields(selected.length == 1 ? selected[0] : null);
// operation isn't recorded on the undo/redo stack
if (undoHandler.isAllowUndo()) {
// Add the node path selection change to the undo/redo stack and
// store the field information in the undo handler
nodeSelect.selectTreePath(getSelectedPaths());
fieldPnlHndlr.storeCurrentFieldInformation();
}
// Reset the flag to allow link tree updates
isNodeSelectionChanging = false;
}
}
};
// Get the references to the group and data field handlers created by the group
// tree. These are used to shorten subsequent calls
groupHandler = groupTree.getGroupHandler();
fieldHandler = groupTree.getFieldHandler();
// Set the data field handler and group tree references in the undo handler so that
// data field and tree edits can be undone/redone
undoHandler.setFieldHandler(fieldHandler);
undoHandler.setTree(groupTree);
// Store the initial group information
copyGroupInformation();
// Create panels to hold the components of the dialog
JPanel titlePnl = new JPanel(new GridBagLayout());
JPanel treePnl = new JPanel(new GridBagLayout());
dialogPnl.setBorder(emptyBorder);
titlePnl.setBorder(emptyBorder);
treePnl.setBorder(emptyBorder);
// Create the group manager dialog labels and fields
JLabel dlgLabel = new JLabel("Assign tables to groups");
dlgLabel.setFont(ModifiableFontInfo.LABEL_BOLD.getFont());
titlePnl.add(dlgLabel, gbc);
// Add the upper panel components to the dialog panel
dialogPnl.add(titlePnl, gbc);
// Build the table tree showing both table prototypes and table instances; i.e.,
// parent tables with their child tables (i.e., parents with children)
tableTree = new CcddTableTreeHandler(ccddMain, null, TableTreeType.TABLES, false, true, ccddMain.getMainFrame()) {
/**
****************************************************************************
* Respond to changes in selection of a node in the table tree
****************************************************************************
*/
@Override
protected void updateTableSelection() {
// Check that a node selection change is not in progress
if (!isNodeSelectionChanging) {
// Select the associated group in the group tree if a table is selected
// in the table tree. Note that below any linked variables are
// deselected, so this call must occur first
selectGroupByTable();
// Set the flag to prevent variable tree updates
isNodeSelectionChanging = true;
// Deselect any nodes that don't represent a table or the level
// immediately above the table level
clearNonTableNodes(1);
// Reset the flag to allow variable tree updates
isNodeSelectionChanging = false;
}
}
};
// Create a table tree panel and add it to another panel (in order to control
// spacing)
gbc.insets.top = 0;
gbc.insets.bottom = ModifiableSpacingInfo.LABEL_VERTICAL_SPACING.getSpacing() / 2;
gbc.weighty = 1.0;
treePnl.add(tableTree.createTreePanel("Tables", TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION, ccddMain.getMainFrame()), gbc);
gbc.insets.top = ModifiableSpacingInfo.LABEL_VERTICAL_SPACING.getSpacing() / 2;
gbc.insets.bottom = 0;
// Create a split pane containing the table tree in the left pane and the group
// tree in the right pane and add it to the panel. The arrow button panel is used
// as the split pane divider
gbc.insets.left = ModifiableSpacingInfo.LABEL_HORIZONTAL_SPACING.getSpacing();
gbc.insets.right = ModifiableSpacingInfo.LABEL_HORIZONTAL_SPACING.getSpacing();
gbc.gridy++;
dialogPnl.add(new CustomSplitPane(treePnl, groupTree.createTreePanel("Groups", TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION, false, ccddMain.getMainFrame()), createArrowButtonPanel(), JSplitPane.HORIZONTAL_SPLIT), gbc);
// Create the field panel for the description and data fields
fieldPnlHndlr = new CcddInputFieldPanelHandler() {
/**
****************************************************************************
* Update the group manager change indicator
****************************************************************************
*/
@Override
protected void updateOwnerChangeIndicator() {
updateChangeIndicator();
}
};
// Set the undo/redo manager and handler for the description and data field values
fieldPnlHndlr.setEditPanelUndo(undoManager, undoHandler);
// Create the description and data fields
fieldPnlHndlr.createDescAndDataFieldPanel(groupMgr, null, null, null, fieldHandler);
// Set the modal undo manager in the keyboard handler while the group manager is
// active
ccddMain.getKeyboardHandler().setModalDialogReference(undoManager, null);
// Re-enable storage of edit actions
undoHandler.setAllowUndo(true);
// Add the field panel to the dialog
gbc.insets.top = ModifiableSpacingInfo.LABEL_VERTICAL_SPACING.getSpacing() / 2;
gbc.insets.left = 0;
gbc.insets.bottom = 0;
gbc.insets.right = 0;
gbc.weighty = 0.0;
gbc.gridy++;
dialogPnl.add(fieldPnlHndlr.getFieldPanel(), gbc);
// Create a check box for showing/changing the group CFS application status
applicationCb = undoHandler.new UndoableCheckBox("Group represents a CFS application", false);
applicationCb.setFont(ModifiableFontInfo.LABEL_BOLD.getFont());
applicationCb.setBorder(emptyBorder);
applicationCb.setEnabled(false);
gbc.insets.top = ModifiableSpacingInfo.LABEL_VERTICAL_SPACING.getSpacing();
gbc.insets.left = ModifiableSpacingInfo.LABEL_HORIZONTAL_SPACING.getSpacing();
gbc.gridy = 0;
fieldPnlHndlr.getFieldPanel().add(applicationCb, gbc, 0);
// Add a listener for the application check box
applicationCb.addActionListener(new ActionListener() {
/**
****************************************************************************
* Handle a change in the application check box status
****************************************************************************
*/
@Override
public void actionPerformed(ActionEvent ae) {
// Check if the application check box is selected and a group is selected
if (((JCheckBox) ae.getSource()).isSelected() && selectedGroup != null) {
// The application check box selection and the added CFS application
// data fields should be a single edit action so that both are removed
// if an undo is performed. Remove the check box selection from the
// undo stack, disable automatic edit sequence ending, then perform the
// check box selection again so that it's added to the undo stack
// without ending the edit sequence
undoManager.undoRemoveEdit();
undoHandler.setAutoEndEditSequence(false);
applicationCb.setSelected(true);
// Get the field information for the group
GroupInformation groupInfo = groupHandler.getGroupInformationByName(selectedGroup.getName());
List<FieldInformation> fieldInformation = groupInfo.getFieldInformation();
// Step through each default application data field
for (DefaultApplicationField field : DefaultApplicationField.values()) {
// Create a new data field
FieldInformation newField = field.createFieldInformation(CcddFieldHandler.getFieldGroupName(selectedGroup.getName()));
boolean isExists = false;
// Step through the group's existing data fields
for (FieldInformation fieldInfo : fieldInformation) {
// Check if the data field already exists
if (newField.getFieldName().equals(fieldInfo.getFieldName())) {
// Set the flag indicating the field exists and stop
// searching
isExists = true;
break;
}
}
// Check if the field doesn't exists
if (!isExists) {
// Add the field to the group
fieldInformation.add(newField);
}
}
// Needed for the group manager dialog's size to be adjusted for the
// data fields
groupMgr.setPreferredSize(null);
// Store the data field additions so that the added fields appear in
// the dialog
fieldHandler.setFieldInformation(CcddFieldHandler.getFieldInformationCopy(fieldInformation));
// Rebuild the data field panel and update the dialog's size
recreateDataFieldPanel(true);
// Re-enable automatic edit sequence ending, then end the edit sequence
// to group the check box and added data fields
undoHandler.setAutoEndEditSequence(true);
undoManager.endEditSequence();
}
}
});
// Define the buttons for the lower panel: New group button
JButton btnNewGroup = CcddButtonPanelHandler.createButton("New", INSERT_ICON, KeyEvent.VK_N, "Create a new group");
// Add a listener for the New button
btnNewGroup.addActionListener(new ActionListener() {
/**
****************************************************************************
* Add a new group
****************************************************************************
*/
@Override
public void actionPerformed(ActionEvent ae) {
newGroup();
}
});
// Delete group button
JButton btnDeleteGroup = CcddButtonPanelHandler.createButton("Delete", DELETE_ICON, KeyEvent.VK_D, "Delete an existing group");
// Add a listener for the Delete button
btnDeleteGroup.addActionListener(new ActionListener() {
/**
****************************************************************************
* Delete the selected group(s)
****************************************************************************
*/
@Override
public void actionPerformed(ActionEvent ae) {
deleteGroup();
}
});
// Rename group button
btnRenameGroup = CcddButtonPanelHandler.createButton("Rename", RENAME_ICON, KeyEvent.VK_D, "Rename an existing group");
// Add a listener for the Rename button
btnRenameGroup.addActionListener(new ActionListener() {
/**
****************************************************************************
* Rename the selected group
****************************************************************************
*/
@Override
public void actionPerformed(ActionEvent ae) {
renameGroup();
}
});
// Copy group button
btnCopyGroup = CcddButtonPanelHandler.createButton("Copy", COPY_ICON, KeyEvent.VK_P, "Copy an existing group");
// Add a listener for the Copy button
btnCopyGroup.addActionListener(new ActionListener() {
/**
****************************************************************************
* Copy the selected group
****************************************************************************
*/
@Override
public void actionPerformed(ActionEvent ae) {
copyGroup();
}
});
// Manage fields button
btnManageFields = CcddButtonPanelHandler.createButton("Fields", FIELD_ICON, KeyEvent.VK_F, "Manage the data fields");
// Add a listener for the Manage Fields command
btnManageFields.addActionListener(new ActionListener() {
/**
****************************************************************************
* Manage the data fields
****************************************************************************
*/
@Override
public void actionPerformed(ActionEvent ae) {
// Create the field editor dialog showing the fields for this group
new CcddFieldEditorDialog(ccddMain, fieldPnlHndlr, CcddFieldHandler.getFieldGroupName(selectedGroup.getName()), false, ModifiableSizeInfo.MIN_DIALOG_WIDTH.getSize());
// Set the undo manager in the keyboard handler back to the group manager
ccddMain.getKeyboardHandler().setModalDialogReference(undoManager, null);
// Enable/disable the Clear values button depending on if any data fields
// remain
btnClearValues.setEnabled(!fieldHandler.getFieldInformation().isEmpty());
}
});
// Clear fields button
btnClearValues = CcddButtonPanelHandler.createButton("Clear", CLEAR_ICON, KeyEvent.VK_C, "Clear the data fields");
// Add a listener for the Clear values command
btnClearValues.addActionListener(new ActionListener() {
/**
****************************************************************************
* Clear the table data field values
****************************************************************************
*/
@Override
public void actionPerformed(ActionEvent ae) {
// Clear all of the data field values for the group
fieldPnlHndlr.clearFieldValues();
}
});
// Undo button
JButton btnUndo = CcddButtonPanelHandler.createButton("Undo", UNDO_ICON, KeyEvent.VK_Z, "Undo the last edit action");
// Create a listener for the Undo command
ActionListener undoAction = new ActionListener() {
/**
****************************************************************************
* Undo the last edit
****************************************************************************
*/
@Override
public void actionPerformed(ActionEvent ae) {
undoManager.undo();
// Update the group selection following an undo
undoHandler.setAllowUndo(false);
groupTree.updateTableSelection();
undoHandler.setAllowUndo(true);
// Update the data field background colors
fieldPnlHndlr.setFieldBackgound();
}
};
// Add the undo listener to the Undo button and menu command
btnUndo.addActionListener(undoAction);
// Redo button
JButton btnRedo = CcddButtonPanelHandler.createButton("Redo", REDO_ICON, KeyEvent.VK_Y, "Redo the last undone edit action");
// Create a listener for the Redo command
ActionListener redoAction = new ActionListener() {
/**
****************************************************************************
* Redo the last cell that was undone
****************************************************************************
*/
@Override
public void actionPerformed(ActionEvent ae) {
undoManager.redo();
// Update the data field background colors
fieldPnlHndlr.setFieldBackgound();
}
};
// Add the redo listener to the Redo button and menu command
btnRedo.addActionListener(redoAction);
// Store groups button
JButton btnStoreGroups = CcddButtonPanelHandler.createButton("Store", STORE_ICON, KeyEvent.VK_S, "Store group updates in the database");
// Add a listener for the Store button
btnStoreGroups.addActionListener(new ActionListener() {
/**
****************************************************************************
* Store the groups in the database
****************************************************************************
*/
@Override
public void actionPerformed(ActionEvent ae) {
// editor is open and has changes that the user confirms discarding them
if (isGroupsChanged() && new CcddDialogHandler().showMessageDialog(groupMgr, "<html><b>Store groups?", "Store Groups", JOptionPane.QUESTION_MESSAGE, DialogOption.OK_CANCEL_OPTION) == OK_BUTTON && ignoreFieldTableChanges()) {
// Store the group list into the database
dbTable.storeInformationTableInBackground(InternalTable.GROUPS, currentGroups, updateFields, deletedGroups, null, null, groupMgr);
}
}
});
// Close button
btnClose = CcddButtonPanelHandler.createButton("Close", CLOSE_ICON, KeyEvent.VK_C, "Close the group manager");
// Add a listener for the Close button
btnClose.addActionListener(new ActionListener() {
/**
****************************************************************************
* Close the group selection dialog
****************************************************************************
*/
@Override
public void actionPerformed(ActionEvent ae) {
// discard the changes
if (!isGroupsChanged() || new CcddDialogHandler().showMessageDialog(groupMgr, "<html><b>Discard changes?", "Discard Changes", JOptionPane.QUESTION_MESSAGE, DialogOption.OK_CANCEL_OPTION) == OK_BUTTON) {
// Close the dialog
closeDialog();
// Clear the modal dialog references in the keyboard handler
ccddMain.getKeyboardHandler().setModalDialogReference(null, null);
}
}
});
// Set the initial enable status of the buttons
setGroupButtonsEnabled(false);
// Add buttons in the order in which they'll appear (left to right, top to bottom)
buttonPnl.add(btnNewGroup);
buttonPnl.add(btnRenameGroup);
buttonPnl.add(btnManageFields);
buttonPnl.add(btnUndo);
buttonPnl.add(btnStoreGroups);
buttonPnl.add(btnDeleteGroup);
buttonPnl.add(btnCopyGroup);
buttonPnl.add(btnClearValues);
buttonPnl.add(btnRedo);
buttonPnl.add(btnClose);
// Distribute the buttons across two rows
setButtonRows(2);
// Update the undo manager so that all group manager edits up to the press of the
// Store button can be undone/redone
fieldPnlHndlr.storeCurrentFieldInformation();
undoManager.endEditSequence();
// Reset the flag now that initialization is complete
isInitializing = false;
}
/**
************************************************************************************
* Group manager dialog creation complete
************************************************************************************
*/
@Override
protected void complete() {
// Display the group manager dialog
showOptionsDialog(ccddMain.getMainFrame(), dialogPnl, buttonPnl, btnClose, DIALOG_TITLE, true);
}
});
}
Aggregations