The controller infrastructure consists of two parts.
- The development of non-visual imitations of swing components (such as TextEdit, ComboBox, Button) used in each form
For example, you can open a form on the server, fill in the controls (components) in that form, and print the form. These imitation classes can work in headless mode on the server as they are not visual parts. - Create a controller class for each form in the form
The controller class for each form contains the methods needed to perform the functions supported by the interface controls on that form in the user interface and without interaction.
When these two parts come together, the controller class of a form on the server side is obtained, the controls inside the form are executed with the imitation classes, and the form functions become available without actually opening the form.
Using
The controller infrastructure can be used in two ways.
Using the Controller from the Menu
The controller codes are used from the menu level on the screen. This usage can often be used for purposes such as server-side data transfer.Using the Controller in Product and Customization Forms
This second use is designed to be used when a product form is being modified by people who develop more customization.
1. Using the Controller from the Menu
The use of the controller starts by opening the controller for a form from the menu.
The ILbsControllerTask interface is implemented for this use. There is only one method on this interface:
public void execute(LbsMenuController menu, IClientContext context);
In this method, any controller can be received via the Lbs Menu Controller class which comes as a parameter.
Thus, the menu, which is normally the starting point for product use, is also the starting point for using the controller.
For example, if you want to transfer materials, then in this task class, the controller class belonging to the material form in the Material Management module is taken from the menu controller class, and the new material creation process is done in the same way as if it is done through the controller belonging to this data list form.
An example usage would be:
public class TestControllerTask implements ILbsControllerTask
{
public void execute(LbsMenuController menu, IClientContext context)
{
try
{
ILbsController controller = menu.launchMaterials();
if(controller instanceof MMXFItemBrowserController)
{
MMXFItemBrowserController itemBrowser =(MMXFItemBrowserController) controller;
ILbsController controller2 = itemBrowser.createNew_CGCommercialGood();
if(controller2 instanceof MMXFItemController)
{
MMXFItemController itemEditor = (MMXFItemController) controller2;
itemEditor.setCode("Material1");
itemEditor.clickSave();
}
}
}
catch (LbsControllerException e)
{
e.printStackTrace();
}
}
}
As you can see, in the code, a new material registration is performed through this class.
There is a helper method to use a class of controls written in this way: The signature of this method in the com.lbs.controllers.LbsControllerUtil class is as follows:
public static void executeControllerTask(final IClientContext clientContext, ILbsControllerTask task) throws Exception
Using this method, a controller job definition can be executed on the server or client.
2. Using the Controller in Product and Customization Forms
In the event handler codes of the product forms, it is possible to get and use the controller class of the form that is open at that time.
This usage is intended for users who are developing more customization.
Working with the controller class of this product form can make it easier to develop an adaptation if the product form is based on a product form with customization.
If normal product forms are also requested, the controller class of the form can be retrieved and used in the event handler codes.
This usage example looks like this:
public class TestFormHandler extends JLbsXUIAdapter
{
public boolean keyPressed(ILbsComponent component, ILbsComponent child, int keyCode, int keyModifiers, ILbsXUIPane container, Object data, IClientContext context)
{
ILbsController controller = container.getController();
if (controller instanceof WFXFTestFormController)
{
WFXFTestFormController testController = (WFXFTestFormController)controller;
try
{
switch (keyCode)
{
case KeyEvent.VK_0:
testController.selectRadio_April();
testController.selectRadio_January();
testController.selectCheckBox_Friday();
testController.selectCheckBox_Sunday();
break;
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
return super.keyPressed(component, child, keyCode, keyModifiers, container, data, context);
}
}
In this example;
Indicates how the controller class is received.
- As you can see, the use of the controller code does not differ from using the controller code.
- In this usage, the components in the form (button, radio button, text edit, etc.) are the swing components seen in the user interface.
- When such a value is entered into a field in the form, the change occurs visually in the form, and the user can see this change
Controller Usage Examples
There are some general principles to be aware of when using controller codes. First of all, if the controller class belonging to an interface form is used, it is necessary to be familiar with this interface form. What is the scenario to be accomplished with the controller codes? First of all, you have to be sure that it works. Any process that can not be performed with user interaction through the interface can not be performed through controller codes. For example, how to enter a value that is not visible (hidden) or restricted in a form can not be done via the controller codes and can not be done in the user interface.
In the controller codes, the order of calling the codes is also important. For example, upper units should be selected first, then lower units connected to this upper unit should be selected. If choosing a warehouse first and then selecting a unit that is not the top unit of this warehouse creates an incorrect statement in the user interface, Failure to observe creates the same faulty condition.
Lookup / Selection with Controller Codes
The user selects this record in the opened form of the record he/she wants to select appears on the first page. If the recording does not appear on the first page, then the user will search and filter to find and select the recording. Since there is no information (image) indicating that the desired record is the 3rd record, in this case, An intellectual target is searched or filtered. This record can be selected after finding the desired search result. An interface has been developed for this process:
public interface ILbsControllerLookupHandler
{
public void lookupControllerOpened(IClientContext context, ILbsController lookupController) throws Exception;
}
There is only one method on this interface. This method is called when the data list form that is expected to be opened for selection is opened on the controller side (in case the form is not opened in the real sense), to do the necessary operations for user selection.
The lookup_ methods in the Controller classes take two parameters. The controller id value of the form that is expected to be opened, which corresponds to the name of the form, MMXFItemBrowser.jfm, for example, is the object that performs this interface and is expected to make a selection from the data list form to be opened. An example usage would be:
MMXFItemController item = (MMXFItemController) controller;
item.setDescription("Item for controllertest");
item.lookup_UnitSet("MMXFUnitSetBrowser.jfm", new ILbsControllerLookupHandler()
{
public void lookupControllerOpened(IClientContext context, ILbsController lookupController) throws Exception
{
if (lookupController instanceof MMXFUnitSetBrowserController)
{
MMXFUnitSetBrowserController unitSets =(MMXFUnitSetBrowserController) lookupController;
UnitSets_Grid100SearchParams params2 =unitSets.getUnitSets_Grid100SearchParams();
params2.setCode("07");
QueryBusinessObjects sets = params2.search();
if (sets.size() = = 1)
{
unitSets.selectGrid100Row(0);
unitSets.clickSelect();
}
else
unitSets.clickClose();
}
}
});
In this example, the selection of the unit set is illustrated in the material editor form. A method to select a set of units is sent to a class that will select the set of units. If the controller belonging to the form opened in the lookup-controller opened method of this class belongs to the unit set data list, it is possible to find the unit set which Is equal to the code "07". If the unit set with code "07" is found, this record is selected and it is expected to close the form and make the selection by pressing the "Select" key in the data list form. If the record is not found, the form is closed by pressing the "Close" key.
Another use that is very similar to Lookup is the process of adding a new record by selecting the record type. Again, the corresponding method is createNewObjectWithType. This method also allows you to select from the data list form opened for the type selection before adding the new record and continue the process. An example usage would be:
FIXFARPSlipBrowserControllerarpSlips = (FIXFARPSlipBrowserController) controller;
controller = arpSlips.createNewObjectWithType("SSXFVTOutlinesBrowser.jfm", new ILbsControllerLookupHandler()
{
public void lookupControllerOpened(IClientContext context, ILbsController lookupController) throws Exception
{
if(lookupController instanceof SSXFVTOutlinesBrowserController)
{
SSXFVTOutlinesBrowserController typeBrowser =(SSXFVTOutlinesBrowserController) lookupController;
SSXFVTOutlinesBrowser_Grid100SearchParams params = typeBrowser.getSSXFVTOutlinesBrowser_Grid100SearchParams();
params.setCode("CARI1");
params.search();
if(typeBrowser.getVisibleRowCountGrid100()= = 1)
{
typeBrowser.selectGrid100Row(0);
typeBrowser.clickSelect();
}
else
throw new Exception("Could not find arpslip type!");
}
}
});
This example is trying to find the type record with the code "CARI1" in the case of opening the type data list form as in the previous example. If there is no record, in this case, an error is made because the operation can not continue.
Message Usage
The user interface may display messages in some warning and error situations or wait for the user to select an option. In the warning and error messages, only the "OK" key is found in the dialogue, which can be more easily handled if there is no user interaction. For example, in places where error messages occur, Throwing (Exception) and stopping the process can be a general solution. But in the messages waiting for a choice from the user, these messages are asked in the process of deleting each object, there is a solution waiting for the user to choose which option the user does not interact with. Within the solution of this problem, each message that can be extracted from the product is listed in the definition of the form issuing this message. Thus, what form each message shows to the user is known in the definition stage. For these messages, some message definition constants are created in the controller classes. Each message has a definition constant, the key (id) of the message, the title of the message, the content of the message, the type (such as error, warning, option) and the options shown in the message dialog. So by looking at the controller class, the user will know which messages to display during operation. The sample message constants are:
public static final Message DATA_SAVE_FAILED = new ErrorMessage("DATA_SAVE_FAILED", "null", "Operationfailed.", new int[] {BUT_OK}, BUT_OK);
public static final Message CONFIRM_DATA_DELETE = new SelectionMessage("CONFIRM_DATA_DELETE", "null", "Delete thisrecord?", new int[] {BUT_CANCEL, BUT_OK}, BUT_CANCEL);
As you can see here, all the information about the message is on these constants.
As in the case of Lookup, when the message is not in use, there is no user interaction. To do this, the corresponding methods of the message in the LbsControllerRegistry class are used. In order to get the class LbsControllerRegistry in each controller class. The getControllerRegistry method is used. There is a message object on the LbsControllerRegistry class. This object implements the ILbsMessageExecutor interface. This interface has the following definition:
public interface ILbsMessageExecutor
{
public JLbsMessageDialogResult onMessageShow(JLbsMessage sourceMessage);
}
In the one-to-one interface of the interface, each message has to be displayed in response to this message, and what to do in response to this message expected from this class. After this class has been written, an object of this class is attached to the LbsControllerRegistry with the setMessageExecutor method of message handling. The use here is left to the design of the person who wrote the code. For example, a class can be created and installed just before an object deletion to respond to a confirmation message that can only occur during object deletion, and this class can be removed when the object deletion is finished.
For messages with type errors by the infrastructure, an error is automatically generated if the message operator class is not installed. Thus, it is prevented from being swallowed without being aware of error conditions. But if a message operator is attached, then, in that case, the class is used exactly as it returns the result. An example usage would be:
ILbsController controller = container.getController();
if (controller instanceof WFXFProcessBrowserController)
{
final WFXFProcessBrowserController processBrowser =(WFXFProcessBrowserController) controller;
processBrowser.selectGrid100Row(0);
processBrowser.getControllerRegistry().setMessageExecutor(new ILbsMessageExecutor()
{
public JLbsMessageDialogResultonMessageShow(JLbsMessage sourceMessage)
{
if (sourceMessage.getId().equals(WFXFProcessBrowserController.CONFIRM_DATA_DELETE.getConstantId()))
{
JLbsMessageDialogResult result = new JLbsMessageDialogResult();
result.button = ILbsMessageConstants.BUT_OK;
return result;
}
throw newLbsControllerRuntimeException("Cannot handle this message: " + sourceMessage);
}
});
processBrowser.clickDelete();
processBrowser.getControllerRegistry().setMessageExecutor(null);
}
As you can see in this example, just before the object deletion process, a message management is installed, and within this operator, only the confirmation message expected to arrive during the deletion is processed and all other unrecognized and unexpected messages are generated. By the end of the deletion, the operator of this message is disassembled so that it is not effective for the messages to be generated after this point.
Other Forms Opened From the Interface
In the user interface, some drop-down menus or forms other than the keys may be opening. In the case of user interaction, there is no problem because the opened form is already visible to the user. However, while controller code is running, it is not possible to get to specific points such as lookups or messages, because it is not known which option or key is likely to open another form. If this is the case, and the user knows about it, then the controller class for that form can be retrieved from the LbsControllerRegistry class using the waitForController method. For example, a change of status in a record usually opens a confirmation interface form for the change of status. A change of state occurs when the user makes a selection regarding the change of state and approves the operation. In order for this scenario to be able to run in the controller part, it must first be known whether the other form will be opened when the status change operation is started on the controller side. Then, at the point where this form is expected to be opened, the controller belonging to this opened form must be acquired and continued with the waitForController method of LbsControllerRegistry class. An example usage would be:
if (itemBrowser.getVisibleRowCountGrid100()> 0)
{
itemBrowser.selectGrid100Row(0);
itemBrowser.selectPopup_ChangeStatus();
controller = itemBrowser.getControllerRegistry().waitForController("MMXFItemStateChange.jfm");
if (controller instanceof MMXFItemStateChangeController)
{
((MMXFItemStateChangeController) controller).clickOK();
}
itemBrowser.refreshGrid100();
}
As you can see in this example, you are expected to open another form when the status change drop-down menu option is selected in the material data list form. This form, which is expected to be opened, is trying to get the form "MMXFItemStateChange.jfm" form and its controller LbsControllerRegistry. If this form is not opened, or if another form is opened, the waitForController method throws an error and the operation can not continue.
Listening to Data Entry
If there are certain operations that are required to be done with data saving operations with emulating controller codes, these data saving operations can be listened with a listener interface. The interface is as follows:
public interface ILbsControllerDataListener
{
public void formDataSaved(ILbsController controller, int savedPrimaryKey);
}
The only metadata in this interface comes with the primary key value of the data that is recorded as the result of any data recording operation. The controller object, which is the first parameter of the method, belongs to the form in which the data registration process takes place. This interface is attached to the LbsControllerRegistry with the setDataListener method like the message listening interface. The point to note when using this interface is that this interface will call the end of all data record operations.