| <MyAddFieldPlugin Project>/src/org/myorg/myaddfieldplugin/AddAtomCountFieldAction.java |
/**
* Creates a new integer Field (database column) in the specified Entity (database table).
* Then invokes a method which fills all rows with data
*/
private static void createNewField(DFEntity entity) {
// For most of the following code please check DFNewType javadoc
// To create new field we need to ask entity for its fields container.
// This container provides so called new types (DFNewType), which can be used for creating
// new fields in the entity. Let's get all available newtypes first
List<DFNewType<DFField>> allNewTypes = entity.getFields().getNewTypes();
// We need a new type which is able to create an integer field. It means DFField which has integer specific
// capability (DFFieldIntegerCapability). We need a standard read/write database column, so we need to avoid
// a new type which creates integer field for chemical terms (DFFieldChemicalTermsCapability).
// So let's use utility method to filter new types.
List<DFNewType<DFField>> appropritateNTs = DIFUtilities.findAllAppropriateNewTypes(allNewTypes, false,
new Class[] { REQUIRED_FIELD_CAPABILITY },
UNDESIRABLE_FIELD_CAPABILITIES);
// We can't do anything if there is no such a new type
if (appropritateNTs.isEmpty()) {
return;
}
// If there are more than one new type which creates integer and non-chemical terms field, let's use the first one
final DFNewType<DFField> nt = appropritateNTs.get(0);
// We need to setup the options (parameters) for new field creation
DFNewTypeOptions unknownNewTypeOptions = nt.getOptions();
// We can use introspection to find out methods/properties which offers this options, but the more simple way
// is to try to cast the given options to some expected well-know new type options. Some of them are predefined
// in DFNewTypeWellKnownOptions interface and serves as a bridge between newtype provider and newtype users.
// In this case we can expect NewDBField subinterface, so let's try it...
if (unknownNewTypeOptions instanceof DFNewTypeWellKnownOptions.NewDBField) {
DFNewTypeWellKnownOptions.NewDBField options = (DFNewTypeWellKnownOptions.NewDBField) unknownNewTypeOptions;
// Setting safe name means that it's validated and if the given name doesn't work, it's "standardized"
// (for example when name is some DB key word, is it's already used, etc.). This method call also generate
// some default database column name.
options.setNewDFItemNameSafe(NEW_FIELD_NAME);
}
String creatingFieldTaskName = NbBundle.getMessage(AddAtomCountFieldAction.class, "MSG_ProgressNameCreatingField");
// The task can take some time, so let's execute it on background using UIBackgroundRunnerRW utility class.
// The method phase1InRequestProcessor is executed on background, during this time the progress bar is moving in IJC main window
// UIBackgroundRunnerRW is also helping with locking before DDL change and unlocking after that. We also need to provide
// progress name and boolean flag if the task is cancellable.
UIBackgroundRunnerRW runner = new UIBackgroundRunnerRW(DIFUtilities.getLockable(entity), creatingFieldTaskName, false) {
private DFField newField;
@Override
public void phase1InRequestProcessor() {
// Let's create the field
newField = nt.create(getEnvironment()).iterator().next();
}
@Override
public void phase2InAWT() {
// phase2 is executed in AWT and it just invokes the method for filling the new field with data.
fillData(newField);
}
};
// task is prepared, we need to start it
runner.start();
}