Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
Difference between revisions of "Scout/Tutorial/3.9/Minicrm/Write the first page"
(New page: {{ScoutPage|cat=Tutorial 3.9}} {{note|Scout Tutorial|This page belongs to the [[{{BASEPAGENAME}}_Step-by-Step|Minicrm Step-by-Step Tutorial]]. It explains how to create your first page in ...) |
(→Create a new service operation in StandardOutlineService) |
||
(5 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
{{ScoutPage|cat=Tutorial 3.9}} | {{ScoutPage|cat=Tutorial 3.9}} | ||
− | {{note|Scout Tutorial|This page belongs to the [[{{BASEPAGENAME}} | + | {{note|Scout Tutorial|This page belongs to the [[{{BASEPAGENAME}}/Minicrm Step-by-Step|Minicrm Step-by-Step Tutorial]]. It explains how to create your first page in your project and fill it with data from the database. You need to [[{{BASEPAGENAME}}/Set up SQL Service|connect a database to your application]] in order to continue.}} |
A typical Eclipse Scout application consists of multiple '''outlines'''. Think of it as a folder hierarchy. Each "folder" is called a '''page'''. These pages come '''with nodes''' (a list of child pages) or '''with a table''' (a table filled with rows of data from a data source such as a database). The '''table''' has named '''columns'''. We need to create models for all of these. | A typical Eclipse Scout application consists of multiple '''outlines'''. Think of it as a folder hierarchy. Each "folder" is called a '''page'''. These pages come '''with nodes''' (a list of child pages) or '''with a table''' (a table filled with rows of data from a data source such as a database). The '''table''' has named '''columns'''. We need to create models for all of these. | ||
Line 30: | Line 30: | ||
All of these structures are strictly client-side structures. The '''server''' couldn't care less about how the various services it provides will get used. The only thing we need on the server side is '''a service that returns tabular company data'''. | All of these structures are strictly client-side structures. The '''server''' couldn't care less about how the various services it provides will get used. The only thing we need on the server side is '''a service that returns tabular company data'''. | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
== Add a Page to the Outline == | == Add a Page to the Outline == | ||
Line 52: | Line 35: | ||
Add a new page to your StandardOutline. Right-click on the ''Child Pages'' node of your ''StandardOutline'' and then choose ''New Page...''. | Add a new page to your StandardOutline. Right-click on the ''Child Pages'' node of your ''StandardOutline'' and then choose ''New Page...''. | ||
− | [[Image:Scout | + | [[Image:Scout.3.9.first_page.new_page.menu.png]] |
From the dropdown list choose '''AbstractPageWithTable''', then click next. | From the dropdown list choose '''AbstractPageWithTable''', then click next. | ||
− | [[Image:Scout | + | [[Image:Scout.3.9.first_page.new_page.wizard.png]] |
Now enter the name for the new table page: ''Company''. | Now enter the name for the new table page: ''Company''. | ||
Line 62: | Line 45: | ||
If there is no appropriate multilingual text, pick ''New translated text...'' from the list and provide a key and a default translation. | If there is no appropriate multilingual text, pick ''New translated text...'' from the list and provide a key and a default translation. | ||
− | [[Image:Scout | + | [[Image:Scout.3.9.new_translated_text.png]] |
− | [[Image:Scout | + | [[Image:Scout.3.9.new_entry.png]] |
− | {{note|Files | + | {{note|Text Property Files|Creating a new translated text will create entries in property files handling translations. ''Texts.properties'' is the file for the default language (the only language available until you add other).}} |
− | Eclipse Scout also comes with an editor to '''edit all the property files for multilingual texts''' in one go. If you expand the ''shared'' node in your Eclipse Scout project, expand ''Text Provider Services'' and click on ''DefaultTextProviderService''. Click the link in the Scout Object properties view. | + | Eclipse Scout also comes with an editor to '''edit all the property files for multilingual texts''' in one go. If you expand the ''shared'' node in your Eclipse Scout project, expand ''Text Provider Services'' and click on ''DefaultTextProviderService''. Click the link in the Scout Object properties view. With this editor you have the possibilty to manage your translated text entries (add, modify, remove), to add or remove a language, to export your entries and so on. {{ScoutLink|SDK|NLS Editor|More information about the NLS Editor here}} |
− | [[Image:Scout | + | [[Image:Scout.3.9.text_provider_service.png]] |
Back to the ''CompanyTablePage'' example: pick ''Company'' from the list (create a new translated text if you haven't done so already) and click ''Finish''. | Back to the ''CompanyTablePage'' example: pick ''Company'' from the list (create a new translated text if you haven't done so already) and click ''Finish''. | ||
− | [[Image:Scout | + | [[Image:Scout.3.9.first_page.new_page.wizard2.png]] |
When you now expand the ''Child Pages'' folder below your ''StandardOutline'', you'll find the new ''CompanyTablePage''. When you expand the node ''Table'', you'll find a folder ''Menus'' and ''Columns''. Below ''Columns'' we will now '''add the columns''' that are needed to display the company data. | When you now expand the ''Child Pages'' folder below your ''StandardOutline'', you'll find the new ''CompanyTablePage''. When you expand the node ''Table'', you'll find a folder ''Menus'' and ''Columns''. Below ''Columns'' we will now '''add the columns''' that are needed to display the company data. | ||
− | [[Image:Scout | + | [[Image:Scout.3.9.first_page.explorer.png]] |
{{note|Files|Creating the Company Table Page has created the file ''eclipse.org.minicrm.client.ui.desktop.outlines.pages/CompanyTablePage.java'' and it has added code to ''eclipse.org.minicrm.client.ui.desktop.outlines/StandardOutline.java''. The newly created method '''execCreateChildPages''' in ''StandardOutline'' shows how child pages are instantiated and added to the list.}} | {{note|Files|Creating the Company Table Page has created the file ''eclipse.org.minicrm.client.ui.desktop.outlines.pages/CompanyTablePage.java'' and it has added code to ''eclipse.org.minicrm.client.ui.desktop.outlines/StandardOutline.java''. The newly created method '''execCreateChildPages''' in ''StandardOutline'' shows how child pages are instantiated and added to the list.}} | ||
Line 88: | Line 71: | ||
The context menu for creating a new table column is on the ''Columns'' node right below the page's table. | The context menu for creating a new table column is on the ''Columns'' node right below the page's table. | ||
− | [[Image:Scout | + | [[Image:Scout.3.9.first_page.new_column.menu.png]] |
First you have to choose a '''template''' for your column. The template used depends on the '''data type''' of your data and the '''format''' you want to use when displaying it. Eclipse Scout will attempt to cast your data types appropriately. | First you have to choose a '''template''' for your column. The template used depends on the '''data type''' of your data and the '''format''' you want to use when displaying it. Eclipse Scout will attempt to cast your data types appropriately. | ||
Line 94: | Line 77: | ||
Choose ''Long Column'' for the first column and ''String Column'' for the remaining columns. | Choose ''Long Column'' for the first column and ''String Column'' for the remaining columns. | ||
− | [[Image: | + | [[Image:Scout.3.9.first_page.new_column.wizard1.png]] |
''CompanyNrColumn'' is going to be an invisible column. Thus, it requires no name. Just provide the ''Type Name''. The remaining columns get multilingual texts for their labels, just like everything else in an Eclipse Scout application. | ''CompanyNrColumn'' is going to be an invisible column. Thus, it requires no name. Just provide the ''Type Name''. The remaining columns get multilingual texts for their labels, just like everything else in an Eclipse Scout application. | ||
− | [[Image:Scout | + | [[Image:Scout.3.9.first_page.new_column.wizard2.png]] |
{| cellspacing=10 style="border-top: 1px solid black; border-bottom: 1px solid black; margin: 1em; " | {| cellspacing=10 style="border-top: 1px solid black; border-bottom: 1px solid black; margin: 1em; " | ||
Line 138: | Line 121: | ||
If you're not sure, use a width of 200 for text columns. | If you're not sure, use a width of 200 for text columns. | ||
− | + | [[Image:Scout.3.9.first_page.column_properties.png]] | |
− | + | ||
− | + | ||
{{note|Properties|Setting properties in the Scout SDK needs to leave traces in the Java code because there is no other storage medium. If you look at the property view, you'll note that all the '''bold''' properties have non-default values. The property names act as links. They'll take you to the source code. Setting the width of a column to 200 results in a method being defined for the inner class modeling the column: <tt>protected int getConfiguredWidth() { return 200; }</tt>. This is how Scout properties are mapped: By overriding methods of the abstract classes the framework provides (such as <tt>AbstractStringColumn</tt> etc.).}} | {{note|Properties|Setting properties in the Scout SDK needs to leave traces in the Java code because there is no other storage medium. If you look at the property view, you'll note that all the '''bold''' properties have non-default values. The property names act as links. They'll take you to the source code. Setting the width of a column to 200 results in a method being defined for the inner class modeling the column: <tt>protected int getConfiguredWidth() { return 200; }</tt>. This is how Scout properties are mapped: By overriding methods of the abstract classes the framework provides (such as <tt>AbstractStringColumn</tt> etc.).}} | ||
Line 155: | Line 136: | ||
Note: There are only two columns | Note: There are only two columns | ||
− | {{note|Visible | + | {{note|Visible vs. Displayable Columns|An invisible column is only invisible initially. Users can right-click on the column headers of a table and ''organize'' their columns. This is where users can show and hide columns, and this is where they can change their order. '''Invisible columns can be made visible''' using this dialog. If you want to prevent users from making invisible columns visible, you must make them ''not displayable''.}} |
Sometimes '''invisible but displayable columns''' are used if a certain table is used like a ''report'' for slightly different target users. Some users are interested in a certain subset of columns, other users are interested in a different subset. Instead of preparing a customized table for every target user, you can provide a single table for all users with specialized columns being invisible but displayable. Every user can then configure the visibility of the particular extra columns they are interested in. | Sometimes '''invisible but displayable columns''' are used if a certain table is used like a ''report'' for slightly different target users. Some users are interested in a certain subset of columns, other users are interested in a different subset. Instead of preparing a customized table for every target user, you can provide a single table for all users with specialized columns being invisible but displayable. Every user can then configure the visibility of the particular extra columns they are interested in. | ||
Line 171: | Line 152: | ||
In order to fill the table in our ''CompanyTablePage'' we need to have a '''service''' available on the server side. This service will contact the database and retrieve the data we need on the client. | In order to fill the table in our ''CompanyTablePage'' we need to have a '''service''' available on the server side. This service will contact the database and retrieve the data we need on the client. | ||
The StandardOutlineService and the interface IStandardOutlineService has already been created. | The StandardOutlineService and the interface IStandardOutlineService has already been created. | ||
− | |||
− | |||
Now we need to add a service operation to the service. | Now we need to add a service operation to the service. | ||
To do so expand the node ''Outline Services'' and you'll see the ''StandardOutlineService''. Right-click on it and choose '''New Service operation'''. | To do so expand the node ''Outline Services'' and you'll see the ''StandardOutlineService''. Right-click on it and choose '''New Service operation'''. | ||
− | [[Image:Scout | + | [[Image:Scout.3.9.first_page.new_service_operation.menu.png]] |
Choose ''getCompanyTableData'' as the name, and a two-dimensional object array <tt>Object[][]</tt> as the return type and click ''Finish''. Now the operation will be added to the interface and the service itself. | Choose ''getCompanyTableData'' as the name, and a two-dimensional object array <tt>Object[][]</tt> as the return type and click ''Finish''. Now the operation will be added to the interface and the service itself. | ||
− | [[Image: | + | [[Image:Scout.3.9.first_page.new_service_operation.wizard.png]] |
{{note|Object[][]|Why aren't we using typed data to communicate between client and server? On the client side, we have a generic ''load table data'' method that needs to return <tt>Object[][]</tt>. It will call the service we just created. Thus, using <tt>Object[][]</tt> when sending tabular data from the server to the client is nothing but a '''shortcut'''.}} | {{note|Object[][]|Why aren't we using typed data to communicate between client and server? On the client side, we have a generic ''load table data'' method that needs to return <tt>Object[][]</tt>. It will call the service we just created. Thus, using <tt>Object[][]</tt> when sending tabular data from the server to the client is nothing but a '''shortcut'''.}} | ||
Line 197: | Line 176: | ||
[[Image:Person.jpg]] | [[Image:Person.jpg]] | ||
− | + | Eclipse Scout provides a base service called <tt>SQL</tt>. In order to access the database and select data, just call <tt>SQL.select(...)</tt>. | |
The first parameter to <tt>SQL.select</tt> is the '''SELECT statement'''. | The first parameter to <tt>SQL.select</tt> is the '''SELECT statement'''. | ||
Line 204: | Line 183: | ||
public class StandardOutlineService extends AbstractService implements IStandardOutlineService { | public class StandardOutlineService extends AbstractService implements IStandardOutlineService { | ||
+ | @Override | ||
public Object[][] getCompanyTableData() throws ProcessingException { | public Object[][] getCompanyTableData() throws ProcessingException { | ||
return SQL.select("" + | return SQL.select("" + | ||
Line 213: | Line 193: | ||
} | } | ||
</source> | </source> | ||
+ | |||
+ | Add the method implementation in the corresponding class: | ||
+ | |||
+ | [[Image:Scout.3.9.first_page.service_operation_implementation.png]] | ||
{{warning|Column order matters|When writing your SELECT statement pay attention to specify the db columns in exactly the same order as the order of your table columns. This is necessarily so because we're just passing an untyped <tt>Object[][]</tt> along. This is an unfortunate consequence of the shortcut we used. As you can see, there are benefits (no packing and unpacking of the tabular data) and drawbacks (the compiler does not check types) to using an untyped <tt>Object[][]</tt>.}} | {{warning|Column order matters|When writing your SELECT statement pay attention to specify the db columns in exactly the same order as the order of your table columns. This is necessarily so because we're just passing an untyped <tt>Object[][]</tt> along. This is an unfortunate consequence of the shortcut we used. As you can see, there are benefits (no packing and unpacking of the tabular data) and drawbacks (the compiler does not check types) to using an untyped <tt>Object[][]</tt>.}} | ||
Line 222: | Line 206: | ||
The last thing to do now is to add the call to the ''getCompanyTableData'' service operation, for this we need to overwrite the method ''AbstractPageWithTable.execLoadTableData(SearchFilter)''. Go back to your ''CompanyTablePage'', in the lower part of the properties view click on the ''+'' right to '''Exec Load Table Data''' in order to create this method in your table page. | The last thing to do now is to add the call to the ''getCompanyTableData'' service operation, for this we need to overwrite the method ''AbstractPageWithTable.execLoadTableData(SearchFilter)''. Go back to your ''CompanyTablePage'', in the lower part of the properties view click on the ''+'' right to '''Exec Load Table Data''' in order to create this method in your table page. | ||
− | + | [[Image:Scout.3.9.first_page.exec_load_table_data.png]] | |
− | [[Image:Scout | + | |
Now you can use the convenience accessor class '''SERVICES''' to find the required service using the ''IStandardOutlineService'' interface class and call ''getCompanyTableData'' to load the data in your TablePage. | Now you can use the convenience accessor class '''SERVICES''' to find the required service using the ''IStandardOutlineService'' interface class and call ''getCompanyTableData'' to load the data in your TablePage. | ||
Line 236: | Line 219: | ||
'''Restart your application''' | '''Restart your application''' | ||
− | [[Image:Scout | + | [[Image:Scout.3.9.first_page.client_swt.png]] |
Latest revision as of 04:18, 27 June 2013
The Scout documentation has been moved to https://eclipsescout.github.io/.
A typical Eclipse Scout application consists of multiple outlines. Think of it as a folder hierarchy. Each "folder" is called a page. These pages come with nodes (a list of child pages) or with a table (a table filled with rows of data from a data source such as a database). The table has named columns. We need to create models for all of these.
If we want to fill the tables with data, we need to create a service on the server side. This service will get data from the database and return tabular data: data arranged in rows and columns which we can use to fill the tables we created on the client side.
Once we have all that we're ready to add a search form to our application.
Contents
What are we talking about?
When we talk about outlines and pages, think of a simple application. In this tutorial we're creating a miniature CRM. Here's what it may look like, using the Eclipse Scout terminology:
- one outline for companies and persons
- the companies page shows a table with rows from the company table on the database
- the persons page shows a table with rows from the person table on the database
- for every person there is a list of nodes naming all the child pages
- there may be other outlines for different tasks or topics, such as marketing campaigns
If you look at the diagram above, there are some interesting things to note.
- the outline itself acts like a page with nodes -- it just shows the titles of the child pages (persons and companies)
- there can be only one child page for a page "with table" -- every row in the table has the same child
- the title of a child page underneath a table is not shown -- by default the first visible column of the table replaces whatever the name was (in the example above "Catherine" replaces whatever the name of the Person Details Page was)
In this tutorial, our first page will be the company table page. The standard outline is a prerequisite, so we'll start there.
All of these structures are strictly client-side structures. The server couldn't care less about how the various services it provides will get used. The only thing we need on the server side is a service that returns tabular company data.
Add a Page to the Outline
Add a new page to your StandardOutline. Right-click on the Child Pages node of your StandardOutline and then choose New Page....
From the dropdown list choose AbstractPageWithTable, then click next.
Now enter the name for the new table page: Company.
If there is no appropriate multilingual text, pick New translated text... from the list and provide a key and a default translation.
Eclipse Scout also comes with an editor to edit all the property files for multilingual texts in one go. If you expand the shared node in your Eclipse Scout project, expand Text Provider Services and click on DefaultTextProviderService. Click the link in the Scout Object properties view. With this editor you have the possibilty to manage your translated text entries (add, modify, remove), to add or remove a language, to export your entries and so on. The Scout documentation has been moved to https://eclipsescout.github.io/.
Back to the CompanyTablePage example: pick Company from the list (create a new translated text if you haven't done so already) and click Finish.
When you now expand the Child Pages folder below your StandardOutline, you'll find the new CompanyTablePage. When you expand the node Table, you'll find a folder Menus and Columns. Below Columns we will now add the columns that are needed to display the company data.
Add colums to the table
The next step is adding columns to the table. Add a column for the primary key (CompanyNrColumn), one for the company's short name (ShortNameColumn) and one for the company's name (NameColumn).
The context menu for creating a new table column is on the Columns node right below the page's table.
First you have to choose a template for your column. The template used depends on the data type of your data and the format you want to use when displaying it. Eclipse Scout will attempt to cast your data types appropriately.
Choose Long Column for the first column and String Column for the remaining columns.
CompanyNrColumn is going to be an invisible column. Thus, it requires no name. Just provide the Type Name. The remaining columns get multilingual texts for their labels, just like everything else in an Eclipse Scout application.
Template | Name | TypeName | Width | Displayable |
---|---|---|---|---|
LongColumn | (none) | CompanyNrColumn | (irrelevant) | no |
StringColumn | Short Name | ShortNameColumn | 200 | yes |
StringColumn | Name | NameColumn | 200 | yes |
Column Width
If you restart your client, you will see that the table layout is not optimal.
The column width could be improved. The table has a property called Auto resize columns and every column has a property called Width. You can either specify a higher width for all of your columns or you can tell your table to auto resize all columns. When auto resizing, the available width is shared by all columns.
If you're not sure, use a width of 200 for text columns.
Hiding Columns
In addition to that, users are typically not interested in primary keys. You should hide CompanyNrColumn from the user.
You can do that by unticking the Visible property on the column. Users can make invisible columns visible, however. If you want to prevent this (and in this case you do), untick the Displayable property. To mark the column as a primary key you have to tick the Primary Key property.
Note: There are only two columns
Sometimes invisible but displayable columns are used if a certain table is used like a report for slightly different target users. Some users are interested in a certain subset of columns, other users are interested in a different subset. Instead of preparing a customized table for every target user, you can provide a single table for all users with specialized columns being invisible but displayable. Every user can then configure the visibility of the particular extra columns they are interested in.
The Flow of Data
Now that we have our user interface, we need to think about flow: how does the data from the database get into our table?
Our table page has a method called execLoadTableData. We will override its default definition and call our outline service instead. In order to do this, we'll get a proxy from the service registry using the SERVICES object and the desired interface (IStandardOutlineService.class) as the key. We call the getCompanyTableData method on the proxy, it gets passed to the server, the method is called, the database is queried via the SQL object, the tabular data is returned to the proxy, it is returned to our function call, finally it will be used to populate the CompanyTablePage model. This in turn will be used to populate the user interface.
Create a new service operation in StandardOutlineService
In order to fill the table in our CompanyTablePage we need to have a service available on the server side. This service will contact the database and retrieve the data we need on the client. The StandardOutlineService and the interface IStandardOutlineService has already been created.
Now we need to add a service operation to the service. To do so expand the node Outline Services and you'll see the StandardOutlineService. Right-click on it and choose New Service operation.
Choose getCompanyTableData as the name, and a two-dimensional object array Object[][] as the return type and click Finish. Now the operation will be added to the interface and the service itself.
When naming service operations that provide tabular data for use in table pages, following the pattern getSomethingTableData is a convention and considered good practice.
Load data on the server
Open the implementation of getCompanyTableData either by expanding the node StandardOutlineService and double-clicking on getCompanyTableData or by opening the class StandardOutlineService directly (Ctrl-Shift-T) and scrolling down to getCompanyTableData. This is the place where we have to add an SQL statement which retrieves the data from the database.
The DB you've downloaded contains the following two tables:
Eclipse Scout provides a base service called SQL. In order to access the database and select data, just call SQL.select(...).
The first parameter to SQL.select is the SELECT statement.
public class StandardOutlineService extends AbstractService implements IStandardOutlineService { @Override public Object[][] getCompanyTableData() throws ProcessingException { return SQL.select("" + "SELECT COMPANY_NR," + " SHORT_NAME," + " NAME" + " FROM COMPANY"); } }
Add the method implementation in the corresponding class:
The optional, second parameter to SQL.select are the Bind Bases. They are needed if you need constraints (a WHERE clause with bind variables) in your SELECT statement. We have no need for them right now, since we're going to select all the companies.
Display data on the client
The last thing to do now is to add the call to the getCompanyTableData service operation, for this we need to overwrite the method AbstractPageWithTable.execLoadTableData(SearchFilter). Go back to your CompanyTablePage, in the lower part of the properties view click on the + right to Exec Load Table Data in order to create this method in your table page.
Now you can use the convenience accessor class SERVICES to find the required service using the IStandardOutlineService interface class and call getCompanyTableData to load the data in your TablePage.
@Override protected Object[][] execLoadTableData(SearchFilter filter) throws ProcessingException { return SERVICES.getService(IStandardOutlineService.class).getCompanyTableData(); }
Restart your application