Search in sources :

Example 1 with UndoableTextField

use of CCDD.CcddUndoHandler.UndoableTextField in project CCDD by nasa.

the class CcddKeyboardHandler method getActiveUndoManager.

/**
 ********************************************************************************************
 * Get the active component's undo manager
 *
 * @return The active undo manager; null if no undo manager is active or no editor has focus
 ********************************************************************************************
 */
private CcddUndoManager getActiveUndoManager() {
    CellEditor cellEditor = null;
    CcddUndoManager undoManager = null;
    editPnlHandler = null;
    // Check if a modal dialog is active
    if (modalUndoManager != null) {
        // Set the undo manager to the modal dialog's undo manager
        undoManager = modalUndoManager;
        // Check if a modal table is active
        if (modalTable != null) {
            // Get the cell editor for the modal table
            cellEditor = modalTable.getCellEditor();
        }
        // Get a reference to the group manager dialog to shorten subsequent calls
        CcddGroupManagerDialog groupManager = ccddMain.getGroupManager();
        // Check if the group manager is open and has focus
        if (groupManager != null && groupManager.isFocused()) {
            // Get the group manager's editor panel handler
            editPnlHandler = groupManager.getEditorPanelHandler();
        }
    } else // No modal undo manager is active
    {
        // Step through each open table editor dialog
        for (CcddTableEditorDialog editorDialog : ccddMain.getTableEditorDialogs()) {
            // Check if this editor dialog has the keyboard focus
            if (editorDialog.isFocused()) {
                // Get the undo manager, cell editor, and editor panel handler for the active
                // table editor
                undoManager = editorDialog.getTableEditor().getFieldPanelUndoManager();
                cellEditor = editorDialog.getTableEditor().getTable().getCellEditor();
                editPnlHandler = editorDialog.getTableEditor().getInputFieldPanelHandler();
            }
            // Check if an undo manager is active
            if (undoManager != null) {
                // Stop searching
                break;
            }
        }
        // Get a reference to the type editor dialog to shorten subsequent calls
        CcddTableTypeEditorDialog editorDialog = ccddMain.getTableTypeEditor();
        // Check if no table undo manager is applicable and the table type editor is open
        if (undoManager == null && editorDialog != null) {
            // Check if the table type editor has the keyboard focus
            if (editorDialog.isFocused()) {
                // Get the undo manager, cell editor, and editor panel handler for the active
                // table type editor
                undoManager = editorDialog.getTypeEditor().getFieldPanelUndoManager();
                cellEditor = editorDialog.getTypeEditor().getTable().getCellEditor();
                editPnlHandler = editorDialog.getTypeEditor().getInputFieldPanelHandler();
            }
        }
        // Get a reference to the data field table editor dialog to shorten subsequent calls
        CcddFieldTableEditorDialog fieldEditor = ccddMain.getFieldTableEditor();
        // editor is open, and the editor has focus
        if (undoManager == null && fieldEditor != null && fieldEditor.isFocused()) {
            // Get the undo manager and cell editor for the data field table editor
            undoManager = fieldEditor.getTable().getUndoManager();
            cellEditor = fieldEditor.getTable().getCellEditor();
        }
        // Get a reference to the script manager dialog to shorten subsequent calls
        CcddScriptManagerDialog scriptManager = ccddMain.getScriptManager();
        // open, and the editor has focus
        if (undoManager == null && scriptManager != null && scriptManager.isFocused()) {
            // Get the undo manager and cell editor for the script manager
            undoManager = ccddMain.getScriptHandler().getAssociationsTable().getUndoManager();
            cellEditor = ccddMain.getScriptHandler().getAssociationsTable().getCellEditor();
        }
    }
    // Check if a table cell is actively being edited
    if (cellEditor != null) {
        // Incorporate any cell changes and terminate editing
        cellEditor.stopCellEditing();
    } else // No table cell is being edited
    {
        // Get the current owner of the keyboard focus
        Component focusOwner = focusManager.getFocusOwner();
        // Check if the focus is in an edit panel's description or data field
        if (focusOwner != null && (focusOwner instanceof UndoableTextField || focusOwner instanceof UndoableTextArea || focusOwner instanceof UndoableCheckBox)) {
            // Check if the focus owner is a text field data field
            if (focusOwner instanceof UndoableTextField) {
                // Force the text to update so that an undo command starts with this field
                ((JTextField) focusOwner).setText(((JTextField) focusOwner).getText());
            }
            // Clear the keyboard focus so that the current data field value is registered as
            // an edit
            focusManager.clearGlobalFocusOwner();
        }
    }
    return undoManager;
}
Also used : UndoableCheckBox(CCDD.CcddUndoHandler.UndoableCheckBox) CellEditor(javax.swing.CellEditor) UndoableTextArea(CCDD.CcddUndoHandler.UndoableTextArea) UndoableTextField(CCDD.CcddUndoHandler.UndoableTextField) Component(java.awt.Component) JTextComponent(javax.swing.text.JTextComponent) JTextField(javax.swing.JTextField)

Example 2 with UndoableTextField

use of CCDD.CcddUndoHandler.UndoableTextField in project CCDD by nasa.

the class CcddFieldTableEditorDialog method doDataFieldUpdatesComplete.

/**
 ********************************************************************************************
 * Perform the steps needed following execution of database table changes
 *
 * @param commandError
 *            false if the database commands successfully completed; true
 ********************************************************************************************
 */
protected void doDataFieldUpdatesComplete(boolean commandError) {
    // Check that no error occurred performing the database commands
    if (!commandError) {
        // Clear the cells selected for deletion
        selectedCells.clear();
        // Load the data field information into the data field editor table
        reloadDataFieldTable();
        // Step through the open editor dialogs
        for (CcddTableEditorDialog editorDialog : ccddMain.getTableEditorDialogs()) {
            // Step through each individual editor in this editor dialog
            for (CcddTableEditorHandler editor : editorDialog.getTableEditors()) {
                List<String> redrawnTables = new ArrayList<String>();
                TableInformation tableInfo = editor.getTableInformation();
                // Step through the data field deletions
                for (String[] del : fieldDeletions) {
                    // already had a deletion applied
                    if (del[0].equals(tableInfo.getTablePath()) && !redrawnTables.contains(del[0])) {
                        // Add the table's name and path to the list of updated tables. This is
                        // used to prevent updating the data fields for a table multiple times
                        redrawnTables.add(del[0]);
                        // Rebuild the table's data field information
                        tableInfo.getFieldHandler().setFieldDefinitions(dataFields);
                        tableInfo.getFieldHandler().buildFieldInformation(del[0]);
                        // Store the data field information in the committed information so
                        // that this value change is ignored when updating or closing the table
                        editor.getCommittedTableInformation().getFieldHandler().setFieldInformation(tableInfo.getFieldHandler().getFieldInformationCopy());
                        // Rebuild the table's editor panel which contains the data fields
                        editor.createDataFieldPanel(false);
                    }
                }
                // Step through the data field value modifications
                for (String[] mod : fieldModifications) {
                    // already been updated by having a deletion applied
                    if (mod[0].equals(tableInfo.getTablePath()) && !redrawnTables.contains(mod[0])) {
                        // Get the reference to the modified field
                        FieldInformation fieldInfo = tableInfo.getFieldHandler().getFieldInformationByName(mod[0], mod[1]);
                        // Update the field's value. Also update the value in the committed
                        // information so that this value change is ignored when updating or
                        // closing the table
                        fieldInfo.setValue(mod[2]);
                        editor.getCommittedTableInformation().getFieldHandler().getFieldInformationByName(mod[0], mod[1]).setValue(mod[2]);
                        // Check that this isn't a boolean input (check box) data field
                        if (fieldInfo.getInputType().getInputFormat() != InputTypeFormat.BOOLEAN) {
                            // Display the updated value in the text field
                            ((UndoableTextField) fieldInfo.getInputFld()).setText(mod[2]);
                        }
                    }
                }
            }
        }
        // Clear the undo/redo cell edits stack
        dataFieldTable.getUndoManager().discardAllEdits();
    }
}
Also used : ArrayList(java.util.ArrayList) TableInformation(CCDD.CcddClassesDataTable.TableInformation) UndoableTextField(CCDD.CcddUndoHandler.UndoableTextField) FieldInformation(CCDD.CcddClassesDataTable.FieldInformation)

Example 3 with UndoableTextField

use of CCDD.CcddUndoHandler.UndoableTextField in project CCDD by nasa.

the class CcddInputFieldPanelHandler method createDataFieldPanel.

/**
 ********************************************************************************************
 * Create the data fields for display in the description and data field panel
 *
 * @param undoable
 *            true if the change(s) to the data fields should be stored for possible undo/redo
 *            operations; false to not store the changes
 ********************************************************************************************
 */
protected void createDataFieldPanel(boolean undoable) {
    maxFieldWidth = 0;
    // Set the preferred size so that the layout manager uses its default sizing
    fieldPnlHndlrOwner.setPreferredSize(null);
    // Check if the data fields are already displayed
    if (fieldPnl != null) {
        // Remove the existing data fields
        inputPnl.remove(fieldPnl);
    }
    // Check if this is a data table
    if (isDataTable) {
        // Build the data field information so that only applicable fields are displayed
        dataFieldHandler.buildFieldInformation(((CcddTableEditorHandler) this).getTableInformation().getTablePath(), ((CcddTableEditorHandler) this).getTableInformation().isRootStructure(), false);
    }
    // Check if any data fields exist
    if (dataFieldHandler.getFieldInformation() != null && !dataFieldHandler.getFieldInformation().isEmpty()) {
        // Create a panel to contain the data fields. As the editor is resized the field panel
        // is resized to contain the data fields, wrapping them to new lines as needed
        fieldPnl = new JPanel(new WrapLayout(FlowLayout.LEADING));
        // Adjust the border to align the first field with the description label
        fieldPnl.setBorder(BorderFactory.createEmptyBorder(-ModifiableSpacingInfo.LABEL_VERTICAL_SPACING.getSpacing(), -ModifiableSpacingInfo.LABEL_HORIZONTAL_SPACING.getSpacing(), 0, 0));
        // Step through each data field
        for (final FieldInformation fieldInfo : dataFieldHandler.getFieldInformation()) {
            switch(fieldInfo.getInputType().getInputFormat()) {
                case PAGE_FORMAT:
                    switch(fieldInfo.getInputType()) {
                        case BREAK:
                            // Create a text field for the separator so it can be handled like
                            // other fields
                            fieldInfo.setInputFld(undoHandler.new UndoableTextField());
                            // Add a vertical separator to the field panel
                            fieldPnl.add(new JSeparator(SwingConstants.VERTICAL));
                            break;
                        case SEPARATOR:
                            // Create a text field for the separator so it can be handled like
                            // other fields
                            fieldInfo.setInputFld(undoHandler.new UndoableTextField());
                            // Add a horizontal separator to the field panel
                            fieldPnl.add(new JSeparator());
                            break;
                        default:
                            break;
                    }
                    break;
                case BOOLEAN:
                    // Create the data field check box
                    fieldInfo.setInputFld(undoHandler.new UndoableCheckBox(fieldInfo.getFieldName(), Boolean.valueOf(fieldInfo.getValue())));
                    UndoableCheckBox booleanCb = (UndoableCheckBox) fieldInfo.getInputFld();
                    booleanCb.setFont(ModifiableFontInfo.LABEL_BOLD.getFont());
                    booleanCb.setForeground(ModifiableColorInfo.SPECIAL_LABEL_TEXT.getColor());
                    // Set the check box's name so that the undo handler can identify the check
                    // box, even if it's destroyed and recreated
                    booleanCb.setName(fieldInfo.getOwnerName() + DATA_FIELD_IDENTIFIER_SEPARATOR + fieldInfo.getFieldName());
                    // Adjust the left and right padding around the check box so that it is
                    // spaced the same as a text field data field
                    booleanCb.setBorder(BorderFactory.createEmptyBorder(0, ModifiableSpacingInfo.LABEL_HORIZONTAL_SPACING.getSpacing(), 0, ModifiableSpacingInfo.LABEL_HORIZONTAL_SPACING.getSpacing()));
                    // Check if a description exists for this field
                    if (!fieldInfo.getDescription().isEmpty()) {
                        // Set the description as the tool tip text for this check box
                        booleanCb.setToolTipText(CcddUtilities.wrapText(fieldInfo.getDescription(), ModifiableSizeInfo.MAX_TOOL_TIP_LENGTH.getSize()));
                    }
                    // And the check box to the field panel
                    fieldPnl.add(booleanCb);
                    // Store this check box's width if it is the largest data field width
                    maxFieldWidth = Math.max(maxFieldWidth, booleanCb.getPreferredSize().width);
                    break;
                default:
                    final JTextComponent inputFld;
                    // Create a panel for a single label and text field pair. This is necessary
                    // so that the two will stay together if line wrapping occurs due to a
                    // window size change
                    JPanel singleFldPnl = new JPanel(new FlowLayout(FlowLayout.LEADING, ModifiableSpacingInfo.LABEL_HORIZONTAL_SPACING.getSpacing(), ModifiableSpacingInfo.LABEL_VERTICAL_SPACING.getSpacing() / 4));
                    singleFldPnl.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
                    // Create the data field label
                    JLabel fieldLbl = new JLabel(fieldInfo.getFieldName());
                    fieldLbl.setFont(ModifiableFontInfo.LABEL_BOLD.getFont());
                    fieldLbl.setForeground(ModifiableColorInfo.SPECIAL_LABEL_TEXT.getColor());
                    singleFldPnl.add(fieldLbl);
                    // Check if the input type is for multi-line text
                    if (fieldInfo.getInputType().equals(InputDataType.TEXT_MULTI)) {
                        // Create the data field input field as a text area, which allows new
                        // line characters which cause the field to be displayed in multiple
                        // rows
                        fieldInfo.setInputFld(undoHandler.new UndoableTextArea(fieldInfo.getValue(), 1, fieldInfo.getSize()));
                        inputFld = (UndoableTextArea) fieldInfo.getInputFld();
                    } else // The input type is one other than for multi-line text
                    {
                        // Create the data field input field as a text field, which allows a
                        // single rows
                        fieldInfo.setInputFld(undoHandler.new UndoableTextField(fieldInfo.getValue(), fieldInfo.getSize()));
                        inputFld = (UndoableTextField) fieldInfo.getInputFld();
                    }
                    inputFld.setFont(ModifiableFontInfo.INPUT_TEXT.getFont());
                    inputFld.setEditable(true);
                    inputFld.setBorder(border);
                    inputFld.setForeground(ModifiableColorInfo.INPUT_TEXT.getColor());
                    inputFld.setBackground(fieldInfo.getValue().isEmpty() && fieldInfo.isRequired() ? ModifiableColorInfo.REQUIRED_BACK.getColor() : ModifiableColorInfo.INPUT_BACK.getColor());
                    // Set the text field's name so that the undo handler can identify the text
                    // field, even if it's destroyed and recreated
                    inputFld.setName(fieldInfo.getOwnerName() + DATA_FIELD_IDENTIFIER_SEPARATOR + fieldInfo.getFieldName());
                    // Check if a description exists for this field
                    if (!fieldInfo.getDescription().isEmpty()) {
                        // Set the description as the tool tip text for this text field
                        inputFld.setToolTipText(CcddUtilities.wrapText(fieldInfo.getDescription(), ModifiableSizeInfo.MAX_TOOL_TIP_LENGTH.getSize()));
                    }
                    // Add the data field to the single field panel
                    singleFldPnl.add(inputFld);
                    // And the single field to the field panel
                    fieldPnl.add(singleFldPnl);
                    // Store this field's width if it is the largest data field width
                    maxFieldWidth = Math.max(maxFieldWidth, singleFldPnl.getPreferredSize().width);
                    // Create an input field verifier for the data field
                    inputFld.setInputVerifier(new InputVerifier() {

                        // Storage for the last valid value entered; used to restore the data
                        // field value if an invalid value is entered. Initialize to the value
                        // at the time the field is created
                        String lastValid = inputFld.getText();

                        /**
                         ********************************************************************
                         * Verify the contents of a the data field
                         ********************************************************************
                         */
                        @Override
                        public boolean verify(JComponent input) {
                            boolean isValid = true;
                            // Get the data field reference to shorten subsequent calls
                            JTextComponent inFld = (JTextComponent) input;
                            // Get the data field contents
                            String inputTxt = inFld.getText();
                            // trailing white space characters
                            if (fieldInfo.getInputType() != InputDataType.TEXT_WHT_SPC && fieldInfo.getInputType() != InputDataType.TEXT_MULTI_WHT_SPC) {
                                // Remove leading and trailing white space characters
                                inputTxt = inputTxt.trim();
                            }
                            // Check if the field contains an illegal character
                            if (!fieldInfo.getInputType().getInputMatch().isEmpty() && !inputTxt.isEmpty() && !inputTxt.matches(fieldInfo.getInputType().getInputMatch())) {
                                // Inform the user that the data field contents is invalid
                                new CcddDialogHandler().showMessageDialog(fieldPnlHndlrOwner, "<html><b>Invalid characters in field '</b>" + fieldInfo.getFieldName() + "<b>'; characters consistent with input type '" + fieldInfo.getInputType().getInputName() + "' expected", "Invalid " + fieldInfo.getInputType().getInputName(), JOptionPane.WARNING_MESSAGE, DialogOption.OK_OPTION);
                                // redrawn correctly
                                if (fieldPnlHndlrOwner instanceof CcddFrameHandler) {
                                    ((CcddFrameHandler) fieldPnlHndlrOwner).setControlsEnabled(false);
                                    ((CcddFrameHandler) fieldPnlHndlrOwner).setControlsEnabled(true);
                                } else if (fieldPnlHndlrOwner instanceof CcddDialogHandler) {
                                    ((CcddDialogHandler) fieldPnlHndlrOwner).setControlsEnabled(false);
                                    ((CcddDialogHandler) fieldPnlHndlrOwner).setControlsEnabled(true);
                                }
                                // Check if the data field is a text field
                                if (input instanceof UndoableTextField) {
                                    // Restore the previous value in the data field
                                    ((UndoableTextField) inFld).setText(lastValid, false);
                                } else // Check if the data field is a text area (multi-line)
                                if (input instanceof UndoableTextArea) {
                                    // Restore the previous value in the data field
                                    ((UndoableTextArea) inFld).setText(lastValid);
                                }
                                // Set the flag to indicate an invalid value was entered
                                isValid = false;
                            } else // The input is valid
                            {
                                // Store the 'cleaned' text back into the text field. For
                                // numeric types, reformat the input value
                                inFld.setText(fieldInfo.getInputType().formatInput(inputTxt));
                                fieldInfo.setValue(inFld.getText());
                                // Store the new value as the last valid value
                                lastValid = inFld.getText();
                                // Set the text field background color. If the field is empty
                                // and is flagged as required then set the background to
                                // indicate a value should be supplied
                                setFieldBackground(fieldInfo);
                            }
                            return isValid;
                        }
                    });
                    break;
            }
        }
        // Check that at least one field exists
        if (fieldPnl.getComponentCount() != 0) {
            // Add the data field panel to the dialog
            inputPnl.add(fieldPnl, gbc);
        }
    }
    // Check if this is a data table
    if (isDataTable) {
        // Build the data field information so that all fields are included
        dataFieldHandler.buildFieldInformation(((CcddTableEditorHandler) this).getTableInformation().getTablePath(), ((CcddTableEditorHandler) this).getTableInformation().isRootStructure(), true);
    }
    // Check if the data field panel change should be put in the undo/redo stack
    if (undoable) {
        // Store the field information in the undo handler in case the update needs to be
        // undone
        undoFieldPnl.addDataFieldEdit(this, dataFieldHandler.getFieldInformationCopy());
    }
    // Force the owner of the editor panel to redraw so that changes to the fields are
    // displayed and the owner's size is adjusted
    fieldPnlHndlrOwner.revalidate();
    fieldPnlHndlrOwner.repaint();
}
Also used : JPanel(javax.swing.JPanel) FlowLayout(java.awt.FlowLayout) JComponent(javax.swing.JComponent) JLabel(javax.swing.JLabel) JTextComponent(javax.swing.text.JTextComponent) UndoableTextField(CCDD.CcddUndoHandler.UndoableTextField) InputVerifier(javax.swing.InputVerifier) WrapLayout(CCDD.CcddClassesComponent.WrapLayout) JSeparator(javax.swing.JSeparator) UndoableCheckBox(CCDD.CcddUndoHandler.UndoableCheckBox) UndoableTextArea(CCDD.CcddUndoHandler.UndoableTextArea) FieldInformation(CCDD.CcddClassesDataTable.FieldInformation)

Aggregations

UndoableTextField (CCDD.CcddUndoHandler.UndoableTextField)3 FieldInformation (CCDD.CcddClassesDataTable.FieldInformation)2 UndoableCheckBox (CCDD.CcddUndoHandler.UndoableCheckBox)2 UndoableTextArea (CCDD.CcddUndoHandler.UndoableTextArea)2 JTextComponent (javax.swing.text.JTextComponent)2 WrapLayout (CCDD.CcddClassesComponent.WrapLayout)1 TableInformation (CCDD.CcddClassesDataTable.TableInformation)1 Component (java.awt.Component)1 FlowLayout (java.awt.FlowLayout)1 ArrayList (java.util.ArrayList)1 CellEditor (javax.swing.CellEditor)1 InputVerifier (javax.swing.InputVerifier)1 JComponent (javax.swing.JComponent)1 JLabel (javax.swing.JLabel)1 JPanel (javax.swing.JPanel)1 JSeparator (javax.swing.JSeparator)1 JTextField (javax.swing.JTextField)1