Create a FormSheet
Description:
Although it is quite easy to initialize and display a FormSheet
, it is a bit difficult to describe how to do it because of the vast opportunities to display them and the many possibilities to use
the FormSheets
and combine them with Components or even JComponents.
The first thing you should do before you create your own FormSheet
is to consult the framework API and take a closer look at
FormSheet
. There you will find all methods and of course the subClasses of FormSheet
, like the LogOnForm
, the MsgForm
or the
TableForms
, which are all specialized FormSheets
of great use.
Talking about the elements, every FormSheet
needs a caption, which is normally defined by calling the constructor and at least some JComponents to display. These can be put
together either by a FormSheetContentCreator
or by creating and overwriting methods within a new FormSheet
instance before or using it's methods during runtime.
It is though recommended to use the ContentCreator as shown in this example, for it is able to serialize the Components and all their properities, esp. their behaviour, which will be lost if you just use
FormSheet
methods and serialize the Shop
's status.
Used classes:
Related topics:
- none
ToDo:
-
Instantiate a subclass of
FormSheetContentCreator
. - Add the constructor and call the superclass to inherit its methods.
-
Add the
protected void createFormSheetContent(FormSheet fs)
method and therein add/remove your components to theFormSheet
. -
Add the
FormSheetContentCreator
to yourFormSheet
class by calling the methodaddContentCreator(FormSheetContentCreator
or by initializing in the constructor.
Example Source Code:
FormSheetContentCreator class:
1 public class DisplayFormSheetContentCreator extends FormSheetContentCreator { 2 public DisplayFormSheetContentCreator() { super(); } 3 protected void createFormSheetContent(FormSheet fs) { // add/remove your components here fs.removeAllButtons(); fs.addButton("TutorialButton", 1, new ArchitectureCustomAction()); } }
Class that uses a FormSheet:
4 // adding the FormSheetContentCreator in FormSheet constructor FormSheet fs = new FormSheet("DisplayFormSheet", new DisplayFormSheetContentCreator(), false); // adding the FormSheetContentCreator by using the addContentCreator method SingleTableFormSheet fs = SingleTableFormSheet.create( "DisplayFormSheet", catalog, uigate); fs.addContentCreator(new DisplayFormSheetContentCreator());
Back to:
Define a FormSheet for a SalesPoint
Description:
The recommended way to define a FormSheet
for a SalesPoint
is to redefine the method getDefaultFormSheet()
of your Salespoint instance,
which is used by the Framework to resolve the FormSheet
which shall be displayed at that SalesPoint
. You may also add a FormSheet
during runtime by using the method setFormSheet(SaleProcess sp, FormSheet fs)
. As you can see, this method is also used to add a SalesProcess
to
the SalesPoint
, which itself is able to display FormSheets
.
This example describes how to add a FormSheet
to the SalesPoint, while the FormSheet
itself should be assembled in a
FormSheetContentCreator
.
Used classes:
Related topics:
ToDo:
-
Redefine the method
getDefaultFormSheet()
in theSalesPoint
class. -
Return the
FormSheet
you want to use.
Example Source Code:
public class DisplaySalesPoint extends SalesPoint { public DisplaySalesPoint(String sName) { super(sName); } 1 protected FormSheet getDefaultFormSheet() { 2 return new FormSheet("DefaultFormSheet", new DisplayFormSheetContentCreator(), false); } }
Back to:
Define a StatusFormSheet for a SalesPoint
Description:
SalesPoints
are being displayed in a separate window but also have a StatusDisplay
at the Shop,
which is the TabbedPane in the Shop's Frame, labled the name of the SalesPoint
. By bringing it on top, it shows
what is defined as the StatusDisplay in your SalesPoint
instance and also adds the Menu defined as
StatusMenuSheet
in the SalesPoint
instance to the Shop's MenuSheet
. By default, both,
the StatusFormSheet
and the StatusMenuSheet
are empty.
Feel free to use the StatusDisplay and MenuSheet
, which are equally handled to the DefaultFormSheet and the
DefaultMenuSheet except that due to the strong division of the Shop
and it's SalesPoints
it is not
possible to have processes running on it. You may trigger a Processes on it, but they will always be displayed by the
SalesPoint
's window. Therefor a more suitable name would be "Statical Display". For further information on
Processes refer to the section "Processes".
This example describes how to define a FormSheet
as the SalesPoint
's StatusFormSheet, while the
FormSheet
itself should be assembled in a FormSheetContentCreator
.
Used classes:
Related topics:
ToDo:
-
Redefine the method
getDefaultStatusFormSheet()
in theSalesPoint
class. -
Return the
FormSheet
you want to use.
Example Source Code:
public class DisplaySalesPoint extends SalesPoint { public DisplaySalesPoint(String sName) { super(sName); } 1 protected FormSheet getDefaultStatusFormSheet() { 2 return new FormSheet("StatusFormSheet", new DisplayFormSheetContentCreator(), false); } }
Back to:
Change the standard OK or CANCEL button behaviour
Description:
A FormSheet
initially has two buttons, one labeled "ok" and one with "cancel" on it. But they don't do anything
by default, so you have to define their behaviour. There are mainly three ways to define the behaviour of the buttons. One is
to create your own FormSheet
and implement the methods ok() and cancel() and the other one is to remove the
buttons and add your own ones with a FormSheetContentCreator
. The second one is more commonly used, because it is
less effort to add two buttons instead of creating lots of new FormSheets
just to define the behaviour of a single
click on a button.
The third one is almost as common but due to the lack of influence on the button's look and feel less used. It's because here
you only set an action to the standard button by resolving it with getButton(int id)
and using
setAction(Action action)
on it. The button's ids are stored as static int in the FormSheet
, where
BTNID_CANCEL
stands for the cancel button and BTNID_OK
for the ok button.
In order to make the behaviour serializable you have to define it within a FormSheetContentCreator
. Otherwise the
information will be lost after loading. It is also possible to alter the buttons design and caption when adding new ones.
Used classes:
Related topics:
ToDo:
-
Initialize a new
FormSheet
. -
Create a new
FormSheetContentCreator
for theFormSheet
and add it. -
In the
protected void createFormSheetContent(FormSheet fs)
method of theFormSheetContentCreator
remove theOK
-Button by callingremoveButton(int id)
. -
Add a new
FormButton
using theaddButton
method. Like here you can shortly add ansale.Action
to the button.
(See also: ). -
Set a new
sale.Action
to theCANCEL
-Button by fetching it with thegetButton(int id)
method and setting the action withsetAction(Action)
.
(See also: ).
Example Source Code:
class where FormSheet is set:
1 FormSheet sheet = new FormSheet("DisplaySheet", null); 2 sheet.addContentCreator(new DisplayFormSheetContentCreator());
FormSheetContentCreator class:
2 public class DisplayFormSheetContentCreator extends FormSheetContentCreator { 3 protected void createFormSheetContent(FormSheet fs) { fs.removeButton(FormSheet.BTNID_OK); 4 fs.addButton("Ok", 102, new DisplayCustomAction()); 5 fs.getButton(FormSheet.BTNID_CANCEL).setAction(new DisplayCustomAction()); } }
Back to:
Define an Action for a FormSheet Button
Description:
The reason for adding buttons to your application is of course to let the user interact with it.
By default, buttons don't have any functions, so you have to add a sale.Action
to the button either by the method
setAction(Action aAction)
provided by the button or by already initializing the button with an action.
Remember to put all this into a FormSheetContentCreator
in order to have the Actions serialized as you save the
Shop's
status. Otherwise all the information will be lost after loading and the buttons will be useless.
Used classes:
Related topics:
ToDo:
-
There are two ways of defining an
Action
:-
Create a class implementing the interface
Action
and add thepublic void doAction(SaleProcess process, SalesPoint point) throws Throwable
method to it. Therein define what to do if the action was called. -
Create an anonymous implementation of
Action
and define what to do if triggered.
-
Create a class implementing the interface
Example Source Code:
1 a public class DisplayCustomAction implements Action { public void doAction(SaleProcess process, SalesPoint point) throws Throwable { // define what shall be done when triggering the action point.runProcess(new DisplaySaleProcess("SampleProcess")); } } 1 b public class DisplaySalesPoint extends SalesPoint { protected FormSheet getDefaultFormSheet() { FormSheet fs = new FormSheet("FormSheet", null); fs.getButton(FormSheet.BTNID_OK).setAction( new Action() { public void doAction(SaleProcess process, SalesPoint point) throws Throwable { // define what shall be done when triggering the action point.runProcess(new DisplaySaleProcess("SampleProcess")); } }); } }
Back to:
Define an Action for a Button in a Component
Description:
Sometimes you will need to add Buttons in the component part of a FormSheet
, since the Button
bar at the bottom may be not sufficient (e.g. too small). This has to be done within a FormSheetContentCreator
when serialization is needed.
Used classes:
Related topics:
ToDo:
-
Create a new
FormSheetContentCreator
with the standard constructor and add thecreateFormSheetContent()
method. -
Create the
JButton
according to your needs. -
Associate the
Action
that should be executed when clicking with the Button. This is done with theActionActionListener
, that takes theAction
itself aswell as theFormSheet
that contains the button. -
Add the button to the FormSheet component. In this case this is done by creating a container
for the button and setting it as FormSheet component. You could also use the
getComponent()
method of the FormSheet and manipulate the component directly (e.g. if it is already a special FormSheet).
Example Source Code:
1 public class DisplayFormSheetContentCreator extends FormSheetContentCreator { public DisplayFormSheetContentCreator() { super(); } protected void createFormSheetContent(FormSheet fs) { 2 JButton button = new JButton("TutorialButton"); 3 button.addActionListener(new ActionActionListener(fs, new DisplayCustomAction())); 4 JPanel container = new JPanel(); container.add(button); fs.setComponent(container); } }
Back to:
Set error handling for a FormSheet
Description:
According to the type of FormSheet you use (and the purpose you use them for), it could be useful to
react on errors occurring in different ways. So it is, for example, not always senseful to stop the
currently running process, whenever an error occurs if you are able to correct it programatically.
Most of the FormSheets use their own
strategies for handling their tasks. Here you can setup the error handlers.
Used classes:
Related topics:
ToDo:
-
Create a new
FormSheetContentCreator
with the standard constructor and add thecreateFormSheetContent()
method. -
Get the FormSheet of the type you need. In our case we assume, we've been given
a
TwoTableFormSheet
and therefore can use it's strategy. -
Set the error handler you need. Basically, there are three possibilities:
-
If the process has to be aborted immediately and an error message
has to be displayed for the user, you can use the
FormSheetStrategy.DEFAULT_ERROR_HANDLER
. This is also set by default, so normally you don't have to do anything in this case. -
If the process can be continued, but a popup dialog shall be used
displaying the error message for the user, you can use the
FormSheetStrategy.MSG_POPUP_ERROR_HANDLER
. - In any other case, you will have to implement your own ErrorHandler.
-
If the process has to be aborted immediately and an error message
has to be displayed for the user, you can use the
Example Source Code:
1 public class DisplayFormSheetContentCreator extends FormSheetContentCreator { public DisplayFormSheetContentCreator() { super(); } protected void createFormSheetContent(FormSheet fs) { 2 TwoTableFormSheet ttfs = (TwoTableFormSheet) fs; 3 a ttfs.getStrategy().setErrorHandler(FormSheetStrategy.DEFAULT_ERROR_HANDLER); 3 b ttfs.getStrategy().setErrorHandler(FormSheetStrategy.MSG_POPUP_ERROR_HANDLER); 3 c ttfs.getStrategy().setErrorHandler(new FormSheetStrategy.ErrorHandler() { public void error(SaleProcess p, int nErrorCode) { System.out.println(p.getErrorMsg(nErrorCode)); } }); } }
Back to:
Standard FormSheet tasks
Description:
As described in "Create a FormSheet", SalesPoint provides you with a vast collection
of standard FormSheets that are able to take care of most of the tasks that will occur in your application.
We will now have a closer look at some tasks and how to solve them.
Related topics:
Display contents of containers:
Containers are all kinds of Catalogs
, Stocks
, user lists and
DataBastkets
that are registered in your Shop. In order to display them, you can use
a SingleTableFormSheet:
SingleTableFormSheet fs = SingleTableFormSheet.create( "DisplayFormSheet", catalog, uigate); fs.addContentCreator(new DisplayFormSheetContentCreator());
You can use any of the container types mentioned above by using the appropriate static create(...)
method of the SingleTableFormSheet
.
Add items to or remove items from containers:
Adding or removing items is a bit more complicated than simply displaying them. In this example, we
will concentrate on adding and removing items in a catalog.
- Create a
SingleTableFormSheet
as needed. Make sure to give the FormSheet exactly the same DataBasket that is currently used. If you are in process, you can simply use it'sgetBasket()
method. If you don't, there will be no valid display update when changes on the container are performed. - Add a new
FormSheetContentCreator
. - If adding items is needed:
- Create an appropriate
EditButtonStrategy
:- If you wish to add items to a catalog, you can use the
AbstractAddCatalogItemStrategy
class. Then you simply have to override it'screateCatalogItem()
method according to your needs and the type of CatalogItem you need. - If you wish to add items to another container, you will have
to create your own
EditButtonStrategy
. You can have a look at theAbstractAddCatalogItemStrategy
as an example.
- If you wish to add items to a catalog, you can use the
- Add the button to the FormSheet. Therefore we have to cast the FormSheet given to a SingleTableFormSheet.
- Create an appropriate
- If deleting items is needed:
- Create an appropriate
EditButtonStrategy
:- If you wish to remove items from a catalog, you can simply use
the
DefaultRemoveCatalogItemStrategy
class. No additional implementations are needed. - If you wish to remove items from another container, you will have
to create your own
EditButtonStrategy
. You can have a look at theDefaultRemoveCatalogItemStrategy
as an example.
- If you wish to remove items from a catalog, you can simply use
the
- Add the button to the FormSheet. Therefore we have to cast the FormSheet given to a SingleTableFormSheet.
- Create an appropriate
// The catalog item needed
public class DisplayCatalogItem extends CatalogItemImpl {
public DisplayCatalogItem(String sName) {
super(sName);
setValue(new DoubleValue(100.0d));
}
protected CatalogItemImpl getShallowClone() {
return null;
}
}
1 SingleTableFormSheet fs = SingleTableFormSheet.create( "DisplayFormSheet", catalog, uigate); 2 fs.addContentCreator(new FormSheetContentCreator() { protected void createFormSheetContent(FormSheet fs) { 3 a EditButtonStrategy ebs = new AbstractAddCatalogItemStrategy(catalog) { protected CatalogItem createCatalogItem(String sKey) { return new DisplayCatalogItem(sKey); } }; 3 b ((SingleTableFormSheet) fs).addAddButton(ebs); 4 a ebs = new DefaultRemoveCatalogItemStrategy(catalog); 4 b ((SingleTableFormSheet) fs).addRemoveButton(ebs); } });
Move items between containers:
In order to move items between containers, you can use the
TwoTableFormSheet,
that has been designed especially for this kind of task. Therefore you choose a source and a
destination container. The FormSheet can move items between them in both directions, depending
on how you wish to use it. There are exactly eleven possible combinations of source and
destination containers:
Source | Destination | Default MoveStrategy |
CountingStock | CountingStock | CSCSStrategy |
StoringStock | StoringStock | SSSSStrategy |
CountingStock | DataBasket | CSDBStrategy |
DataBasket | CountingStock | DBCSStrategy |
StoringStock | DataBasket | SSDBStrategy |
DataBasket | StoringStock | DBSSStrategy |
Catalog | Catalog | CCStrategy |
Catalog | DataBasket | CDBStrategy |
DataBasket | Catalog | DBCStrategy |
Catalog | StoringStock | CSSStrategy
Attention: You need to override the createStockItem() method,
as it is application dependent. |
Catalog | CountingStock | CCSStrategy |
You can refer to the individual documentations on how they exactly work. When creating the
TwoTableFormSheet
, simply use the create()
that you need (giving null
as DataBasket means the FormSheet will work outside any transitional context, causing all data manipulations
to be executed immediately, without any rollback possibilities).
private FormSheet getMoveContentFormSheet(UIGate uigate, Catalog cSource, Catalog cDest) { TwoTableFormSheet ttfs = TwoTableFormSheet.create("Title", cSource, cDest, (DataBasket)null, uigate, TwoTableFormSheet.RIGHT); return ttfs; }
Back to:
Update a formsheet display
Description:
A common problem is notifying FormSheets
that the data, or at least a part of it, has
been changed by some process. Now it shall display the new data.
The solution for this task is to use DataBaskets
in the right way. You do not tell the
formsheet that it shall update itself, rather you tell the modified data element to notify all it's
listeners to update all their necessary parts (e.g. table cells).
Used classes:
Related topics:
- none
ToDo:
-
Create a new
DataBasket
. -
Retrieve the CatalogItem relative to the DataBasket and tell the
get
method to prepare the item for editing. After that you can manipulate it in any way you want. -
Call the DataBasket's
commit
method. This will put the updated item back in the container appropriately and tells all listeners such as visual display components to update themselves.
Example Source Code:
1 DataBasket db = new DataBasketImpl(); 2 CatalogItem ci = catalog.get("TheItemsKey", db, true); 3 db.commit();
Back to:
Data Management: Common | Display: MenuSheet |