B4J Question ABMaterial - simple tutorial needed

semar

Active Member
Licensed User
Longtime User
Hi all,
I find ABMaterial for B4J very interesting, however, since I'm complete new on it - and on B4J in general - I wonder if someone could share some experience about.

Basically I want to build an on-line language training.

For example, in an exercise an english sentence should appear, where a word is missing. The user should fill that gap in the sentence, and press a button. The Webapp should react accordingly on what the user wrote, for instance, if the answer is correct, a green sign should appear by the sentence, if wrong a red one.

Note that all the text for the sentence and the right answer, and the title of the exercise, pictures and the like should come from a database - and/or files - that is, the text and some other fiields on the site should be dinamically filled with content from a data source - a database, a file - which resides on the server.

Since I'm still at the beginning phase of this project, I wonder if ABMaterial could help me to reach this goal, or instead would be better to manually code it using the 'classical' way, that is, the html + css3 + jquery + ajax + (add other framework here) route.

This is the most important question, that could be answered from some experienced user of ABMaterial - or from the ABMaterial creator ;).

The second question, not less important: are there easy to understand tutorials on ABMaterial ? For instance, starting from the 'template':
- how can I build, for example, a page with only a label and an input text field, while the text in the text field is dinamically generated from within the Webapp ?
- How can I set the (absolute or relative) position of the fields on the generated page ?
- Which files (.bas) are needed in the B4J project ? I ask this because even when I load the project 'Template', there are several .bas files that are included, and I wonder if they all are needed.
- Is there an WYSIWYG editor for building a page ? Which tool should I use in order to position the fields on the page ?

All in all I find ABMaterial very impressive. However, in order to get the resulted B4J App working, you need a server where the compiled .jar file is hosted and running on it. In my opinion, this is a disavantage compared with the 'classical' route with html, css, jquery, ajax, which does not need any running .jar.
However, it adds lots of more interactivity than a 'simple' html page with jquery code, and writing the code using B4J is way more fun than script editing, IMHO.

I have the feeling that the use of ABMaterial could speed up the development and also would contribute to obtain a nice looking responsive site, which would compensate the added complexity in the deployment department.

Please feel free to post your opinions on this topic. This is very important for me, in order to make the right decision.

Best regards,
Sergio.

P.S.
I apologize if this post is in the wrong forum. I really didn't find another suitable place for it. Feel free to move if needed. Thank you.
 
Last edited:

OliverA

Expert
Licensed User
Longtime User
In my opinion, this is a disavantage compared with the 'classical' route with html, css, jquery, ajax, which does not need any running .jar.
However, it adds lots of more interactivity than a 'simple' html page with jquery code, and writing the code using B4J is way more fun than script editing, IMHO.
Either option is going to require learning. The question is, would you like to keep up with HTML, CSS, AJAX, whatever flavor of the day AJAX library (jquery for now), JavaScript or would you like to learn B4J and ABMaterial. It's really up to you.

he second question, not less important: are there easy to understand tutorials on ABMaterial ?
Look at the ABMFeedback application. May not be totally "easy", but it covers quite some ground. As being specific to what you want, I don't think that too many frameworks provide user specific tutorials. If there is for HTML+CSS+AJAX+jQuery+JavaScript, then that may get you going faster.

- How can I set the (absolute or relative) position of the fields on the generated page ?
My question: What is with the fascination of setting absolute positions? Learn the grid.

- Which files (.bas) are needed in the B4J project ? I ask this because even when I load the project 'Template', there are several .bas files that are included, and I wonder if they all are needed.
If you don't use a database, you can skip DBM.bas. You have to pick between ABMPateTemplate.bas and ABMPageTemplateAlternative.bas for you pages, so the one you don't pick can be discarded (in the end both, for distribution). If you don't upload files, you will not need ABMUploadHander.bas.

- Is there an WYSIWYG editor for building a page ? Which tool should I use in order to position the fields on the page ?
WYSIWYG, no. For the creating of the grid, use ABMGridBuilder.

All in all I find ABMaterial very impressive. However, in order to get the resulted B4J App working, you need a server where the compiled .jar file is hosted and running on it. In my opinion, this is a disavantage compared with the 'classical' route with html, css, jquery, ajax, which does not need any running .jar.
If that is an issue (running .jar files on a server), then don't use ABMaterial.

Finally, you could also look at this (https://www.b4x.com/android/forum/threads/webapp-web-apps-overview.39811/#content)(pick the example with MySQL for faster startup), which may get you going faster without some of the great features of ABMaterial and then when you're ready for more, switch to ABMaterial.
 
Upvote 0

semar

Active Member
Licensed User
Longtime User
Thank you OliverA for your insights and tips.

The idea to start with pure B4J-Webapps is really not bad, however starting directly with ABMaterial would lead me quickly to something closer to what I would like to achieve. That's why I'm in the needing of simple tutorials.

I've looked into the ABMFeedback application. I've added the requested mysql jar needed and it compiles fine, however, I can't really reach the app with the browser as I succeed with the other demos. Which is the name I have to use, the App name in the Main or should I use the directory name of the Application ?
I've tried
- http://localhost:51042/ABMFeedback
- http://localhost:51042/feedback --> like stated in ABMShared
- http://localhost:51042/abmfeedback

but still no joy.
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
I'm pretty sure the port # is 51044, but you can check for yourself in the Main module of the feedback application. Look for
B4X:
myApp.StartServer(srvr, "srvr", xxxxx)
where xxxxx is the port number. So if it is 51044, then this
should work.
 
Upvote 0

Mashiane

Expert
Licensed User
Longtime User
@semar , my advise to anyone who wants to start using ABMaterial is for them to be prepared to learn. The creator of this framework has done a very good job in providing examples of all the components within the Demo app itself and also posted stuff within the forum including other example apps bundled with the downloads. All other members who use the framework also ask questions and get responses within this forum.

As you might / will find out, one of the first challenging parts for newbies is the grid and understanding how it works. @OliverA is right that you need to start there. The first point will be to design what you need to have including the various components perhaps on a piece of paper then use the ABMGridDesigner to replicate what you did, then export your grid definition to your ABMPage. The grid definition itself does not have components but with it at least you have a way of knowing where your components will sit so its very close to what an IDE is for ABMaterial for now. As long as you know where your components should be, then just focus on a grid design to suit that purpose and then use your RC (row and column) co-ordinates to .AddComponent or .AddArrayComponent.

There are also two important page methods that you can use, these are page.DebugPrintGrid but preferably page.ShowGridInfo to display your grid 'outline' on your page etc. Also you can direct your webapp execution to log files which can detail how this are with your app and I bet see problem areas.

In part, this framework has a monitor and a debugger built into it that you can turn on and off during development to see problem areas and also execution of your code.

Good luck and all the best.
 
Upvote 0

semar

Active Member
Licensed User
Longtime User
@OliverA ,
yes the port number did the trick, many thanks !
However, login and password are needed..

@Mashiane ,
thanks for your comment and hints. Yes you' re right, there's a lot to learn in order to master ABMaterial, that's why I've just started a learn-by-doing project !

By the way, I'm proud to belong to the ABMaterial donators !

Best regards,
Sergio
 
Last edited:
Upvote 0

OliverA

Expert
Licensed User
Longtime User
However, login and password are needed
Out of the box it's Admin for both the username and password (case sensitive). This information is found in the DBM.bas file.
 
Upvote 0

inakigarm

Well-Known Member
Licensed User
Longtime User
I think that the feedback DB is not included on ABMFeedback; you have to look at ABMApplication.bas to search the code for user's login; when this page is loaded; first it shows a modal login dialog; if the user is in the database, the Web initialpage is loaded

This is a modification I've made for my project:
B4X:
Private Sub WebSocket_Connected (WebSocket1 As WebSocket)
    Log("Connected")
    ws = WebSocket1
   
    ABMPageId = ABM.GetPageID(AppPage, ABMShared.AppName,ws)
    Dim session As HttpSession = ABM.GetSession(ws, ABMShared.SessionMaxInactiveIntervalSeconds) 'ignore
   
    ' Prepare the page IMPORTANT!
    AppPage.Prepare   
   
    ' navigate to the first page
    If ABMShared.NeedsAuthorization Then
        If ws.Session.GetAttribute2("IsAuthorized", "") = "" Then
            Dim loginpwd As String = ABM.LoadLogin(AppPage, ABMShared.AppName)
            If loginpwd <> "" Then
                Dim SQL As SQL = DBM.GetSQL
                Dim split() As String = Regex.Split(";", loginpwd)
               
                Dim vars As List
                vars.Initialize
                vars.Add(split(0))
                vars.Add(split(1))
                Dim users As List = DBM.SQLSelect(SQL, "SELECT * FROM users WHERE UserLogin=? AND UserPassword=?", vars)
               
                'Dim users As List = DBM.SQLSelect(SQL, "SELECT * FROM users WHERE UserLogin='" & split(0) & "' AND UserPassword='" & split(1) & "'")
                If users.Size > 0 Then   
                    Dim user As Map = users.Get(0)
                    ws.Session.SetAttribute("authType", "local")
                    ws.Session.SetAttribute("authName", split(0))
                    ws.Session.SetAttribute("IsAuthorized", "true")
                    ws.Session.SetAttribute("UserType", "" & user.Get("usertype") )    ' lowercase!               
                    ws.Session.SetAttribute("UserID", "" & user.Get("userid") ) ' lowercase!
                    ws.Session.SetAttribute("Username", "" & user.Get("username") )
                    ABMShared.NavigateToPage(ws, ABMPageId, "./" & InitialPage)
                    DBM.CloseSQL(SQL)
                    Return   
                End If
                DBM.CloseSQL(SQL)
            End If
            AppPage.ShowModalSheet("login")
            Return
        End If
    End If
    ABMShared.NavigateToPage(ws, ABMPageId, "./" & InitialPage)
End Sub
 
Upvote 0

semar

Active Member
Licensed User
Longtime User
I think that the feedback DB is not included on ABMFeedback
Yes I think so too !
Is that DB a MySql DB ? Should I create it ? I could install XAMPP for example, which comes with a MySql database. The rest should be done from code with the create table commands. But I don't know if this is the correct path to follow.
What have you done in order to get the feedback project running ?
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Is that DB a MySql DB ?
Yes
Should I create it ?
Yes
The rest should be done from code with the create table commands
Yes

Looking at the 3.75 code of the feedback app, the DBM.InitializeMySQL method is commented out (in the Main module). If you have a MySQL server up and running, then un-comment and adjust. I guess this is part of the learning curve.
 
Upvote 0

semar

Active Member
Licensed User
Longtime User
I've created a mysql called abmfeedback. The DB is up and running, I can browse it with phpmyadmin.
I've uncommented the line as suggested by OliverA and tried both of these lines:
DBM.InitializeMySQL("localhost", "anUserid", "aPassword", 100)
DBM.InitializeMySQL("localhost:3306", "anUserid", "aPassword", 100)
DBM.InitializeMySQL("localhost:3306\abnfeedback", "anUserid", "aPassword", 100)

I get an error stating that I don't have a suitable driver:
B4X:
Waiting for debugger to connect...
Program started.
init mysql
Nov 13, 2017 5:55:31 PM com.mchange.v2.log.MLog
INFORMATION: MLog clients using java 1.4+ standard logging.
Nov 13, 2017 5:55:31 PM com.mchange.v2.c3p0.C3P0Registry
INFORMATION: Initializing c3p0-0.9.5.2 [built 08-December-2015 22:06:04 -0800; debug? true; trace: 10]
Nov 13, 2017 5:55:32 PM com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource
INFORMATION: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 20000, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, dataSourceName -> 1hgf02c9r1el0n8m1wekirx|574caa3f, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, extensions -> {}, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, forceUseNamedDriverClass -> false, identityToken -> 1hgf02c9r1el0n8m1wekirx|574caa3f, idleConnectionTestPeriod -> 600, initialPoolSize -> 3, jdbcUrl -> localhost:3308, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 1800, maxIdleTimeExcessConnections -> 0, maxP...
Nov 13, 2017 5:56:02 PM com.mchange.v2.resourcepool.BasicResourcePool
WARNUNG: com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask@327ca692 -- Acquisition Attempt Failed!!! Clearing pending acquires. While trying to acquire a needed new resource, we failed to succeed more than the maximum number of allowed acquisition attempts (30). Last acquisition attempt exception:
java.sql.SQLException: No suitable driver
   at java.sql.DriverManager.getDriver(DriverManager.java:315)
   at com.mchange.v2.c3p0.DriverManagerDataSource.driver(DriverManagerDataSource.java:285)
   at com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:175)
   at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:220)
   at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:206)
   at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:203)
   at com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1138)
   at com.mchange.v2.resourcepool.BasicResourcePool.doAcquireAndDecrementPendingAcquiresWithinLockOnSuccess(BasicResourcePool.java:1125)
   at com.mchange.v2.resourcepool.BasicResourcePool.access$700(BasicResourcePool.java:44)
   at com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask.run(BasicResourcePool.java:1870)
   at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:696)
Nov 13, 2017 5:56:02 PM com.mchange.v2.resourcepool.BasicResourcePool
WARNUNG: Having failed to acquire a resource, com.mchange.v2.resourcepool.BasicResourcePool@4590c9c3 is interrupting all Threads waiting on a resource to check out. Will try again in response to new client requests.
Nov 13, 2017 5:56:02 PM com.mchange.v2.resourcepool.BasicResourcePool
WARNUNG: com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask@53e7f672 -- Acquisition Attempt Failed!!! Clearing pending acquires. While trying to acquire a needed new resource, we failed to succeed more than the maximum number of allowed acquisition attempts (30). Last acquisition attempt exception:
java.sql.SQLException: No suitable driver
   at java.sql.DriverManager.getDriver(DriverManager.java:315)
   at com.mchange.v2.c3p0.DriverManagerDataSource.driver(DriverManagerDataSource.java:285)
   at com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:175)
   at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:220)
   at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:206)
   at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:203)
   at com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1138)
   at com.mchange.v2.resourcepool.BasicResourcePool.doAcquireAndDecrementPendingAcquiresWithinLockOnSuccess(BasicResourcePool.java:1125)
   at com.mchange.v2.resourcepool.BasicResourcePool.access$700(BasicResourcePool.java:44)
   at com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask.run(BasicResourcePool.java:1870)
   at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:696)
Nov 13, 2017 5:56:02 PM com.mchange.v2.resourcepool.BasicResourcePool
WARNUNG: Having failed to acquire a resource, com.mchange.v2.resourcepool.BasicResourcePool@4590c9c3 is interrupting all Threads waiting on a resource to check out. Will try again in response to new client requests.
Nov 13, 2017 5:56:02 PM com.mchange.v2.resourcepool.BasicResourcePool
WARNUNG: com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask@4564974c -- Acquisition Attempt Failed!!! Clearing pending acquires. While trying to acquire a needed new resource, we failed to succeed more than the maximum number of allowed acquisition attempts (30). Last acquisition attempt exception:
java.sql.SQLException: No suitable driver
   at java.sql.DriverManager.getDriver(DriverManager.java:315)
   at com.mchange.v2.c3p0.DriverManagerDataSource.driver(DriverManagerDataSource.java:285)
   at com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:175)
   at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:220)
   at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:206)
   at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:203)
   at com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1138)
   at com.mchange.v2.resourcepool.BasicResourcePool.doAcquireAndDecrementPendingAcquiresWithinLockOnSuccess(BasicResourcePool.java:1125)
   at com.mchange.v2.resourcepool.BasicResourcePool.access$700(BasicResourcePool.java:44)
   at com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask.run(BasicResourcePool.java:1870)
   at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:696)
Nov 13, 2017 5:56:02 PM com.mchange.v2.resourcepool.BasicResourcePool
WARNUNG: Having failed to acquire a resource, com.mchange.v2.resourcepool.BasicResourcePool@4590c9c3 is interrupting all Threads waiting on a resource to check out. Will try again in response to new client requests.
Error occurred on line: 29 (DBM)
java.sql.SQLException: An attempt by a client to checkout a Connection has timed out.
   at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:118)
   at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:77)
   at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:690)
   at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:140)
   at anywheresoftware.b4j.object.ConnectionPool.GetConnection(ConnectionPool.java:45)
   at abmfeedback.ab.com.dbm._getsql(dbm.java:195)
   at abmfeedback.ab.com.dbm._createtablesifneeded(dbm.java:76)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
   at java.lang.reflect.Method.invoke(Method.java:497)
   at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:613)
   at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:228)
   at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:159)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
   at java.lang.reflect.Method.invoke(Method.java:497)
   at anywheresoftware.b4a.BA.raiseEvent2(BA.java:90)
   at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:93)
   at anywheresoftware.b4a.BA.raiseEvent(BA.java:77)
   at abmfeedback.ab.com.main.main(main.java:29)
Caused by: com.mchange.v2.resourcepool.TimeoutException: A client timed out while waiting to acquire a resource from com.mchange.v2.resourcepool.BasicResourcePool@4590c9c3 -- timeout at awaitAvailable()
   at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1467)
   at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:644)
   at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:554)
   at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutAndMarkConnectionInUse(C3P0PooledConnectionPool.java:758)
   at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:685)
   ... 19 more
However, I have configured a path directory from within B4J where I've put a downloaded .jar mysql driver: mysql-connector-java-5.1.37-bin.jar
as requested in the source code (in main).
Did you have added some additional .jar elsewhere ?
 
Last edited:
Upvote 0

semar

Active Member
Licensed User
Longtime User
I've already added the mysql-connector-java-5.1.27-bin.jar to the B4J library, but I think it would be better to add it inside ABMaterial library.

Anyway I've got the ABMFeedback-App working. The command line to connect to a MySql DB is in my case:
B4X:
DBM.InitializeMySQL("jdbc:mysql://localhost/abmfeedback", "myuser", "mypassword", 100)

A question: from within Firefox 44.02 the ABMaterial App does not show like it should. Perhaps should I update it to the new version, but before to do so: is the Firefox browser compatible with ABMaterial ?
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
I've already added the mysql-connector-java-5.1.27-bin.jar to the B4J library, but I think it would be better to add it inside ABMaterial library.
Did you set up an Additional Libraries folder in the B4J IDE? That's where additional libraries go (such as ABM and JDBC drivers). When you compile the app, the "#MergeLibraries: True" option will include any necessary .jar files in the build (and you don't have to worry about including them manually when distributing your app).
 
Upvote 0

semar

Active Member
Licensed User
Longtime User
Did you set up an Additional Libraries folder in the B4J IDE? That's where additional libraries go (such as ABM and JDBC drivers). When you compile the app, the "#MergeLibraries: True" option will include any necessary .jar files in the build (and you don't have to worry about including them manually when distributing your app).
Fantastic, thank you !
Let me say that the ABMaterial-Feedback App is quite impressive !
 
Last edited:
Upvote 0
Top