B4J Tutorial [ABMaterial] For Dummies (beginner lessons)

ABMaterial For Dummies

This has often been asked for - so it is high time to produce a simple set of guidelines to help get you across the short learning curve. Take your time and see what you have been missing in simplifying web app creation with ABMaterial!

IMPORTANT UPDATE
------------------------------------------------------------------------------------------------------------------
@alwaysbusy created THIS wonderful and simple tutorial on May 3rd, 2020.
[ABMaterial] Mini Template for absolute beginners
------------------------------------------------------------------------------------------------------------------

*************************************************************
Having problems with your great understanding ABM?
Check the links with lessons 8 and 9 below for solutions..

*************************************************************

PLEASE - DO NOT Post QUESTIONS here!
It only serves to muddy the waters of a clean flow.


PLEASE
- Post any questions / comments in the B4J Questions forum (title - ABM for dummies).

If you have a request for something not covered here - please post it. We shall try to accomodate.

Lesson 1 - Master Template Project (covers Grids, BuildPage and ConnectPage). Required! - Contains all files for ABMaterial projects
Lesson 1a - More on ABM Grids ( Rows and Cells )

Lesson 2 - Simple ABMLogin with Public / Private Pages

Lesson 3 - MySQL and CRUD / ABMTables
Lesson 3a - More about ABMTables

Lesson 4 - Working With Containers

Lesson 5 - ABMGenerator
Lesson 5a - Report Setup

Lesson 6 - Sample Next Reports

Lesson 7 - ABMGenerator revisited (includes ABMTable)

Lesson 8 - Deployment Problems (Local Development vs Server Differences)
https://www.b4x.com/android/forum/threads/abmaterial-for-dummies-beginner-lessons.88346/#post-609895

Lesson 9 - Tips and Tricks
https://www.b4x.com/android/forum/threads/abmaterial-for-dummies-beginner-lessons.88346/page-2#post-611983

On the surface, ABMaterial appears to be a complex framework - which in fact, it is. However, through the series of specific topics (new posts), we will expose how easy it is to use - and construct beautiful / functional web apps.

The first post in this series (ok, the second) will have a complete project based on @alwaysbusy (empty) Template project included in each version he releases. It shall use ABM version 4.03 which is available to everyone. This well documented example will expose the Template page (populated with controls), a simple About page and the ABMShared code module containing the navigation bar and component themes. This is generally enough to get a newcomer started - since it actually does something!

We encourage others who are proficient with ABM to contribute well documented examples to this tutorial. Usually, this will be in the form of a stand alone "page" that can be added to the project, and any support methods needed which should go into the ABMShared code module.
For the pupil, he/she will download your .bas and add it to the project, create a menu item in the nav bar, add requirements in Main to initialize and any methods for ABMShared.

Many lessons (new posts) will be added with simple sections - as not to over-complicate matters.

Here is a small sample of what to expect:
B4X:
public Sub ConnectPage()
    ' connecting the navigation bar - now that we have built one above...
    ' examine the code in ABMShared to see how this works...
    ABMShared.ConnectNavigationBar(page)


    ' Let's add some components to the page - labels (with text), buttons and other controls...
    ' page.Cell(1,1).AddComponent(ABMShared.BuildLabel - here we add a label component to Row 1 / Cell 1, using a single statement
    ' and a method found in ABMShared Code Module.
    ' page.Cell(1,1).AddComponent(ABMShared.BuildLabel(page, "basic1",  - each component MUST have a Unique ID ("basic1" in this case)
    ' Notice that the text is right-justified...  How???  Using a theme - "lbltheme1"
    ' I will let you discover what the other parameters are for this method...
    page.Cell(1,1).AddComponent(ABMShared.BuildLabel(page, "basic1",   "See the faint green dot above in title bar?  This means your websocket is connected! {BR} All of this page's code is explained in the source file! {BR}{NBSP}",  ABM.SIZE_H4, "lbltheme1", 0, "25px"))

    ' Here we add another component in Row 2, Cell 1 - It is essentially a label with block quote
    page.Cell(2,1).AddComponent(ABMShared.BuildParagraphBQWithZDepth(page, "basic13",   "Hi There!  I am in Row 2 of this page!   {BR}{BR} I Have 'Flow Text' Applied. What does that mean? Resize this browser window and watch THIS text size shrink and grow accordingly!" ))

    ' Lets do something different in Row 3...
'.............................................

templatepage.jpg


The second post will have a link to download the base project - since it is much too large to attach here.


Thanks
 

Attachments

  • about.jpg
    399.4 KB · Views: 1,532
Last edited:

Mashiane

Expert
Licensed User
Longtime User
ABMaterial Form Controls Getter & Setter Methods

This looks into how one can get / set component values by calling the various methods of the defined components/controls.

  • ABMEditor - GetHTML / SetHTML
  • ABMImage - Source / SourceToggle, image path set on initialize
  • ABMRadio - GetActive / SetActive use AddRadioButton or AddRadioButtonNoLineBreak to add items after initialization
  • ABMCheckBox - State
  • ABMCombo - GetActiveItemId / SetActiveItemId, use AddItem to add item after initialization
  • ABMDateTimePicker/ABMDateTimeScroller - GetDate / SetDate / SetDateISO and value set on initialize
  • ABMInput - Text (Includes TextArea)
  • ABMSwitch - State, OnText, OffText
  • ABMFileInput - GetFileName, Accepts & also on change event. Uses UploadToServer method to upload file to server
  • ABMSignature - GetDrawingURI, saved to a file.
  • ABMRange - GetStart & GetStop, SetStart & SetStop & values set on initialize
  • ABMSlider - GetValue / SetValue & values set on initialize
  • ABMPatternLock - get value on change event
 

Mashiane

Expert
Licensed User
Longtime User
ABMaterial Enumeration Constants Quick Reference: For more details explore the XML document

ABM comes up with built in constants that one can use when initializing / setting up some components. These fortunately are prefixed by the relevant control they relate to. For example, any constant relating to the ActionButton is prefixed with ACTIONBUTTON.

B4X:
Dim ABM As ABMaterial
ABM.ACTIONBUTTON_DIRECTION_DOWN
ABM.ACTIONBUTTON_DIRECTION_LEFT
ABM.ACTIONBUTTON_DIRECTION_RIGHT
ABM.ACTIONBUTTON_DIRECTION_UP
ABM.ACTIONBUTTON_POSITION_BOTTOMLEFT
ABM.ACTIONBUTTON_POSITION_BOTTOMRIGHT
ABM.ACTIONBUTTON_POSITION_TOPLEFT
ABM.ACTIONBUTTON_POSITION_TOPRIGHT
ABM.AUTOCOMPLETE_CONTAINS
ABM.AUTOCOMPLETE_GOOGLE
ABM.AUTOCOMPLETE_STARTS
ABM.B4JS_PARAM_ACTIONMAINBUTTON
ABM.B4JS_PARAM_ACTIONSUBBUTTON
ABM.B4JS_PARAM_INPUTKEY
ABM.B4JS_PARAM_INPUTKEYCODE
ABM.B4JS_PARAM_RANGESTART
ABM.B4JS_PARAM_RANGESTOP
ABM.B4JS_PARAM_SLIDERVALUE
ABM.B4JS_PARAM_TABSRETURNNAME
ABM.BORDER_DASHED
ABM.BORDER_DEFAULT
ABM.BORDER_DOTTED
ABM.BORDER_DOUBLE
ABM.BORDER_GROOVE
ABM.BORDER_HIDDEN
ABM.BORDER_INSET
ABM.BORDER_NONE
ABM.BORDER_OUTSET
ABM.BORDER_RIDGE
ABM.BORDER_SOLID
ABM.BUTTONSIZE_LARGE
ABM.BUTTONSIZE_NORMAL
ABM.BUTTONSIZE_SMALL
ABM.CALENDAR_DEFAULTVIEW_DAY
ABM.CALENDAR_DEFAULTVIEW_MONTH
ABM.CALENDAR_DEFAULTVIEW_WEEK
ABM.CANVAS_LINECAP_BUTT
ABM.CANVAS_LINECAP_ROUND
ABM.CANVAS_LINECAP_SQUARE
ABM.CANVAS_LINEJOIN_BEVEL
ABM.CANVAS_LINEJOIN_MITER
ABM.CANVAS_LINEJOIN_ROUND
ABM.CANVAS_OPERATION_COPY
ABM.CANVAS_OPERATION_DESTINATIONATOP
ABM.CANVAS_OPERATION_DESTINATIONIN
ABM.CANVAS_OPERATION_DESTINATIONOUT
ABM.CANVAS_OPERATION_DESTINATIONOVER
ABM.CANVAS_OPERATION_LIGHTER
ABM.CANVAS_OPERATION_SOURCEATOP
ABM.CANVAS_OPERATION_SOURCEIN
ABM.CANVAS_OPERATION_SOURCEOUT
ABM.CANVAS_OPERATION_SOURCEOVER
ABM.CANVAS_OPERATION_XOR
ABM.CANVAS_TEXTALIGN_CENTER
ABM.CANVAS_TEXTALIGN_END
ABM.CANVAS_TEXTALIGN_LEFT
ABM.CANVAS_TEXTALIGN_RIGHT
ABM.CANVAS_TEXTALIGN_START
ABM.CANVAS_TEXTBASELINE_ALPHABETIC
ABM.CANVAS_TEXTBASELINE_BOTTOM
ABM.CANVAS_TEXTBASELINE_HANGING
ABM.CANVAS_TEXTBASELINE_IDEOGRAPHIC
ABM.CANVAS_TEXTBASELINE_MIDDLE
ABM.CANVAS_TEXTBASELINE_TOP
ABM.CANVAS_TEXTSTYLE_ITALIC
ABM.CANVAS_TEXTSTYLE_NORMAL
ABM.CANVAS_TEXTSTYLE_OBLIQUE
ABM.CANVAS_TEXTVARIANT_NORMAL
ABM.CANVAS_TEXTVARIANT_SMALLCAPS
ABM.CANVAS_TEXTWEIGHT_100
ABM.CANVAS_TEXTWEIGHT_200
ABM.CANVAS_TEXTWEIGHT_300
ABM.CANVAS_TEXTWEIGHT_400
ABM.CANVAS_TEXTWEIGHT_500
ABM.CANVAS_TEXTWEIGHT_600
ABM.CANVAS_TEXTWEIGHT_700
ABM.CANVAS_TEXTWEIGHT_800
ABM.CANVAS_TEXTWEIGHT_900
ABM.CANVAS_TEXTWEIGHT_BOLD
ABM.CANVAS_TEXTWEIGHT_BOLDER
ABM.CANVAS_TEXTWEIGHT_LIGHTER
ABM.CANVAS_TEXTWEIGHT_NORMAL
ABM.CARD_LARGE
ABM.CARD_MEDIUM
ABM.CARD_NOTSPECIFIED
ABM.CARD_SMALL
ABM.CELL_ALIGN_CENTER
ABM.CELL_ALIGN_JUSTIFY
ABM.CELL_ALIGN_LEFT
ABM.CELL_ALIGN_RIGHT
ABM.CHART_AXISTYPE_AUTOSCALEAXIS
ABM.CHART_AXISTYPE_FIXEDSCALEAXIS
ABM.CHART_AXISTYPE_STEPAXIS
ABM.CHART_AXISTYPE_UNDEFINED
ABM.CHART_LABELDIRECTION_EXPLODE
ABM.CHART_LABELDIRECTION_IMPLODE
ABM.CHART_LABELDIRECTION_NEUTRAL
ABM.CHART_LABELPOSITION_CENTER
ABM.CHART_LABELPOSITION_INSIDE
ABM.CHART_LABELPOSITION_OUTSIDE
ABM.CHART_LINESMOOTH_CARDINAL
ABM.CHART_LINESMOOTH_NONE
ABM.CHART_LINESMOOTH_SIMPLE
ABM.CHART_LINESMOOTH_STEP
ABM.CHART_POSITION_END
ABM.CHART_POSITION_START
ABM.CHART_RATIO_DOUBLEOCTAVE
ABM.CHART_RATIO_GOLDENSECTION
ABM.CHART_RATIO_MAJORELEVENTH
ABM.CHART_RATIO_MAJORSECOND
ABM.CHART_RATIO_MAJORSEVENTH
ABM.CHART_RATIO_MAJORSIXTH
ABM.CHART_RATIO_MAJORTENTH
ABM.CHART_RATIO_MAJORTHIRD
ABM.CHART_RATIO_MAJORTWELFTH
ABM.CHART_RATIO_MINORSECOND
ABM.CHART_RATIO_MINORSEVENTH
ABM.CHART_RATIO_MINORSIXTH
ABM.CHART_RATIO_MINORTHIRD
ABM.CHART_RATIO_OCTAVE
ABM.CHART_RATIO_PERFECTFIFTH
ABM.CHART_RATIO_PERFECTFORTH
ABM.CHART_RATIO_SQUARE
ABM.CHART_SERIEINDEX_A
ABM.CHART_SERIEINDEX_B
ABM.CHART_SERIEINDEX_C
ABM.CHART_SERIEINDEX_D
ABM.CHART_SERIEINDEX_E
ABM.CHART_SERIEINDEX_F
ABM.CHART_SERIEINDEX_G
ABM.CHART_SERIEINDEX_H
ABM.CHART_SERIEINDEX_I
ABM.CHART_SERIEINDEX_J
ABM.CHART_SERIEINDEX_K
ABM.CHART_SERIEINDEX_L
ABM.CHART_SERIEINDEX_M
ABM.CHART_SERIEINDEX_N
ABM.CHART_SERIEINDEX_O
ABM.CHART_TYPEBAR
ABM.CHART_TYPELINE
ABM.CHART_TYPEPIE
ABM.COLLAPSE_ACCORDION
ABM.COLLAPSE_EXPANDABLE
ABM.COLLAPSE_NONE
ABM.COLOR_AMBER
ABM.COLOR_BLACK
ABM.COLOR_BLUE
ABM.COLOR_BLUEGREY
ABM.COLOR_BROWN
ABM.COLOR_CYAN
ABM.COLOR_DEEPORANGE
ABM.COLOR_DEEPPURPLE
ABM.COLOR_GREEN
ABM.COLOR_GREY
ABM.COLOR_INDIGO
ABM.COLOR_LIGHTBLUE
ABM.COLOR_LIGHTGREEN
ABM.COLOR_LIME
ABM.COLOR_ORANGE
ABM.COLOR_PINK
ABM.COLOR_PURPLE
ABM.COLOR_RED
ABM.COLOR_TEAL
ABM.COLOR_TRANSPARENT
ABM.COLOR_WHITE
ABM.COLOR_YELLOW
ABM.COMBO_DATA_BELOWINPUT
ABM.COMBO_DATA_FLOATING
ABM.CONTAINERBORDER_DASHED
ABM.CONTAINERBORDER_DEFAULT
ABM.CONTAINERBORDER_DOTTED
ABM.CONTAINERBORDER_DOUBLE
ABM.CONTAINERBORDER_GROOVE
ABM.CONTAINERBORDER_HIDDEN
ABM.CONTAINERBORDER_INSET
ABM.CONTAINERBORDER_NONE
ABM.CONTAINERBORDER_OUTSET
ABM.CONTAINERBORDER_RIDGE
ABM.CONTAINERBORDER_SOLID
ABM.CONTAINERIMAGE_POSITION_CENTERBOTTOM
ABM.CONTAINERIMAGE_POSITION_CENTERCENTER
ABM.CONTAINERIMAGE_POSITION_CENTERTOP
ABM.CONTAINERIMAGE_POSITION_COVER
ABM.CONTAINERIMAGE_POSITION_LEFTBOTTOM
ABM.CONTAINERIMAGE_POSITION_LEFTCENTER
ABM.CONTAINERIMAGE_POSITION_LEFTTOP
ABM.CONTAINERIMAGE_POSITION_RIGHTBOTTOM
ABM.CONTAINERIMAGE_POSITION_RIGHTCENTER
ABM.CONTAINERIMAGE_POSITION_RIGHTTOP
ABM.CONTAINERIMAGE_REPEAT_NOREPEAT
ABM.CONTAINERIMAGE_REPEAT_REPEAT
ABM.CONTAINERIMAGE_REPEAT_REPEAT_X
ABM.CONTAINERIMAGE_REPEAT_REPEAT_Y
ABM.CURSOR_CELL
ABM.CURSOR_COL_RESIZING
ABM.CURSOR_DEFAULT
ABM.CURSOR_DENY
ABM.CURSOR_H_RESIZING
ABM.CURSOR_LOADING
ABM.CURSOR_MOVING
ABM.CURSOR_NONE
ABM.CURSOR_POINTING
ABM.CURSOR_TYPING
ABM.CURSOR_V_RESIZING
ABM.CURSOR_WAITING
ABM.CURSOR_ZOOM_IN
ABM.CURSOR_ZOOM_OUT
ABM.DATETIMEPICKER_TYPE_DATE
ABM.DATETIMEPICKER_TYPE_DATETIME
ABM.DATETIMEPICKER_TYPE_TIME
ABM.DATETIMEPICKER_TYPE_WEEK
ABM.DATETIMESCROLLER_MODE_CLICKPICK
ABM.DATETIMESCROLLER_MODE_MIXED
ABM.DATETIMESCROLLER_MODE_SCROLLER
ABM.DATETIMESCROLLER_TYPE_DATE
ABM.DATETIMESCROLLER_TYPE_DATETIME
ABM.DATETIMESCROLLER_TYPE_TIME
ABM.FIRSTDAYOFWEEK_FRIDAY
ABM.FIRSTDAYOFWEEK_MONDAY
ABM.FIRSTDAYOFWEEK_SATURDAY
ABM.FIRSTDAYOFWEEK_SUNDAY
ABM.FIRSTDAYOFWEEK_THURSDAY
ABM.FIRSTDAYOFWEEK_TUESDAY
ABM.FIRSTDAYOFWEEK_WEDNESDAY
ABM.FLOATING_FROMBOTTOM
ABM.FLOATING_FROMTOP
ABM.GEN_CHECKBOX
ABM.GEN_COMBOLIST
ABM.GEN_COMBOSQL
ABM.GEN_DATETIME_PICK
ABM.GEN_DATETIME_SCROLL
ABM.GEN_DATE_PICK
ABM.GEN_DATE_SCROLL
ABM.GEN_DOUBLE
ABM.GEN_INTEGER
ABM.GEN_NONE
ABM.GEN_SWITCH
ABM.GEN_TEXT
ABM.GEN_TEXTAREA
ABM.GEN_TIME_PICK
ABM.GEN_TIME_SCROLL
ABM.GOOGLEMAPTYPE_HYBRID
ABM.GOOGLEMAPTYPE_ROADMAP
ABM.GOOGLEMAPTYPE_SATELLITE
ABM.GOOGLEMAPTYPE_TERRAIN
ABM.GOOGLEMAP_TRAVELMODE_BICYCLING
ABM.GOOGLEMAP_TRAVELMODE_DRIVING
ABM.GOOGLEMAP_TRAVELMODE_TRANSIT
ABM.GOOGLEMAP_TRAVELMODE_WALKING
ABM.GOOGLE_AUTOCOMLETE_RESULTTYPE_CITY
ABM.GOOGLE_AUTOCOMLETE_RESULTTYPE_COUNTRY
ABM.GOOGLE_AUTOCOMLETE_RESULTTYPE_LOCATION
ABM.GOOGLE_AUTOCOMLETE_RESULTTYPE_POSTALCODE
ABM.GOOGLE_AUTOCOMLETE_RESULTTYPE_STATE
ABM.GOOGLE_AUTOCOMLETE_RESULTTYPE_STREETNAME
ABM.GOOGLE_AUTOCOMLETE_RESULTTYPE_STREETNUMBER
ABM.HALFBUTTON_CENTER
ABM.HALFBUTTON_LEFT
ABM.HALFBUTTON_RIGHT
ABM.ICONALIGN_CENTER
ABM.ICONALIGN_LEFT
ABM.ICONALIGN_RIGHT
ABM.ICONBADGE_POSITION_BOTTOMLEFT
ABM.ICONBADGE_POSITION_BOTTOMRIGHT
ABM.ICONBADGE_POSITION_TOPLEFT
ABM.ICONBADGE_POSITION_TOPRIGHT
ABM.ICONSIZE_LARGE
ABM.ICONSIZE_MEDIUM
ABM.ICONSIZE_SMALL
ABM.ICONSIZE_TINY
ABM.IMAGESLIDER_CENTER
ABM.IMAGESLIDER_LEFT
ABM.IMAGESLIDER_RIGHT
ABM.INPUTBOX_QUESTIONTYPE_CHECKBOX
ABM.INPUTBOX_QUESTIONTYPE_EMAIL
ABM.INPUTBOX_QUESTIONTYPE_PASSWORD
ABM.INPUTBOX_QUESTIONTYPE_RADIO
ABM.INPUTBOX_QUESTIONTYPE_TEXT
ABM.INPUTBOX_QUESTIONTYPE_TEXTAREA
ABM.INPUTBOX_RESULT_CANCEL
ABM.INPUTBOX_RESULT_CLOSE
ABM.INPUTBOX_RESULT_ESC
ABM.INPUTBOX_RESULT_INVALID
ABM.INPUTBOX_RESULT_OVERLAY
ABM.INPUTBOX_TYPE_ERROR
ABM.INPUTBOX_TYPE_INFO
ABM.INPUTBOX_TYPE_QUESTION
ABM.INPUTBOX_TYPE_SUCCESS
ABM.INPUTBOX_TYPE_WARNING
ABM.INPUT_DATE
ABM.INPUT_DATETIMELOCAL
ABM.INPUT_EMAIL
ABM.INPUT_NUMBER
ABM.INPUT_PASSWORD
ABM.INPUT_SEARCH
ABM.INPUT_TEL
ABM.INPUT_TEXT
ABM.INPUT_TEXTALIGN_CENTER
ABM.INPUT_TEXTALIGN_END
ABM.INPUT_TEXTALIGN_LEFT
ABM.INPUT_TEXTALIGN_RIGHT
ABM.INPUT_TEXTALIGN_START
ABM.INPUT_TIME
ABM.INPUT_URL
ABM.INTENSITY_ACCENT1
ABM.INTENSITY_ACCENT2
ABM.INTENSITY_ACCENT3
ABM.INTENSITY_ACCENT4
ABM.INTENSITY_DARKEN1
ABM.INTENSITY_DARKEN2
ABM.INTENSITY_DARKEN3
ABM.INTENSITY_DARKEN4
ABM.INTENSITY_LIGHTEN1
ABM.INTENSITY_LIGHTEN2
ABM.INTENSITY_LIGHTEN3
ABM.INTENSITY_LIGHTEN4
ABM.INTENSITY_LIGHTEN5
ABM.INTENSITY_NORMAL
ABM.ITEMLIST_TYPE_ALPHABET_LOWERCASE
ABM.ITEMLIST_TYPE_ALPHABET_UPPERCASE
ABM.ITEMLIST_TYPE_CIRCLE
ABM.ITEMLIST_TYPE_DISC
ABM.ITEMLIST_TYPE_NONE
ABM.ITEMLIST_TYPE_NUMBERS
ABM.ITEMLIST_TYPE_ROMAN_LOWERCASE
ABM.ITEMLIST_TYPE_ROMAN_UPPERCASE
ABM.ITEMLIST_TYPE_SQUARE
ABM.LOADER_TYPE_AUTO
ABM.LOADER_TYPE_MANUAL
ABM.MODALSHEET_SIZE_FULL
ABM.MODALSHEET_SIZE_LARGE
ABM.MODALSHEET_SIZE_NORMAL
ABM.MODALSHEET_TYPE_BOTTOM
ABM.MODALSHEET_TYPE_NORMAL
ABM.MODALSHEET_TYPE_TOP
ABM.MSGBOX_POS_BOTTOM_CENTER
ABM.MSGBOX_POS_BOTTOM_LEFT
ABM.MSGBOX_POS_BOTTOM_RIGHT
ABM.MSGBOX_POS_CENTER_CENTER
ABM.MSGBOX_POS_CENTER_LEFT
ABM.MSGBOX_POS_CENTER_RIGHT
ABM.MSGBOX_POS_TOP_CENTER
ABM.MSGBOX_POS_TOP_LEFT
ABM.MSGBOX_POS_TOP_RIGHT
ABM.MSGBOX_RESULT_CANCEL
ABM.MSGBOX_RESULT_CLOSE
ABM.MSGBOX_RESULT_ESC
ABM.MSGBOX_RESULT_OK
ABM.MSGBOX_RESULT_OVERLAY
ABM.MSGBOX_TYPE_ERROR
ABM.MSGBOX_TYPE_INFO
ABM.MSGBOX_TYPE_NOICON
ABM.MSGBOX_TYPE_QUESTION
ABM.MSGBOX_TYPE_SUCCESS
ABM.MSGBOX_TYPE_WARNING
ABM.NATIVE_PLATFORM_B4A
ABM.NATIVE_PLATFORM_B4J
ABM.NATIVE_PLATFORM_B4i
ABM.NATIVE_PLATFORM_NONE
ABM.PAGE_INLINE_FALSE
ABM.PAGE_INLINE_TRUE
ABM.PAGE_INLINE_USEAPPSETTING
ABM.PAGE_OPENGRAPH_COUNTRYNAME
ABM.PAGE_OPENGRAPH_DESCRIPTION
ABM.PAGE_OPENGRAPH_EMAIL
ABM.PAGE_OPENGRAPH_FAXNUMBER
ABM.PAGE_OPENGRAPH_IMAGE
ABM.PAGE_OPENGRAPH_IMAGEHEIGHT
ABM.PAGE_OPENGRAPH_IMAGEWIDTH
ABM.PAGE_OPENGRAPH_LATITUDE
ABM.PAGE_OPENGRAPH_LOCALE
ABM.PAGE_OPENGRAPH_LOCALITY
ABM.PAGE_OPENGRAPH_LONGITUDE
ABM.PAGE_OPENGRAPH_PHONENUMBER
ABM.PAGE_OPENGRAPH_POSTALCODE
ABM.PAGE_OPENGRAPH_REGION
ABM.PAGE_OPENGRAPH_SITENAME
ABM.PAGE_OPENGRAPH_STREETADDRESS
ABM.PAGE_OPENGRAPH_TITLE
ABM.PAGE_OPENGRAPH_TYPE
ABM.PAGE_OPENGRAPH_URL
ABM.PAGE_TWITTER_CARD
ABM.PAGE_TWITTER_CREATOR
ABM.PAGE_TWITTER_CREATORID
ABM.PAGE_TWITTER_DESCRIPTION
ABM.PAGE_TWITTER_IMAGE
ABM.PAGE_TWITTER_IMAGEHEIGHT
ABM.PAGE_TWITTER_IMAGEWIDTH
ABM.PAGE_TWITTER_PLAYER
ABM.PAGE_TWITTER_PLAYERHEIGHT
ABM.PAGE_TWITTER_PLAYERWIDTH
ABM.PAGE_TWITTER_SITE
ABM.PAGE_TWITTER_SITEID
ABM.PAGE_TWITTER_STREAM
ABM.PAGE_TWITTER_TITLE
ABM.PAGE_TWITTER_URL
ABM.PDF_READDIRECTION_LTR
ABM.PDF_READDIRECTION_RTL
ABM.PIVOT_AGGRTYPE_80LOWERBOUND
ABM.PIVOT_AGGRTYPE_80UPPERBOUND
ABM.PIVOT_AGGRTYPE_AVERAGE
ABM.PIVOT_AGGRTYPE_COUNT
ABM.PIVOT_AGGRTYPE_COUNTASFRACTIONCOLS
ABM.PIVOT_AGGRTYPE_COUNTASFRACTIONROWS
ABM.PIVOT_AGGRTYPE_COUNTASFRACTIONTOTAL
ABM.PIVOT_AGGRTYPE_COUNTUNIQUEVALUES
ABM.PIVOT_AGGRTYPE_FIRST
ABM.PIVOT_AGGRTYPE_INTEGERSIM
ABM.PIVOT_AGGRTYPE_LAST
ABM.PIVOT_AGGRTYPE_LISTUNIQUEVALUES
ABM.PIVOT_AGGRTYPE_MAXIMUM
ABM.PIVOT_AGGRTYPE_MINIMUM
ABM.PIVOT_AGGRTYPE_SUM
ABM.PIVOT_AGGRTYPE_SUMASFRACTIONCOLS
ABM.PIVOT_AGGRTYPE_SUMASFRACTIONROWS
ABM.PIVOT_AGGRTYPE_SUMASFRACTIONTOTAL
ABM.PIVOT_AGGRTYPE_SUMOVERSUM
ABM.PIVOT_TABLETYPE_COLHEATMAP
ABM.PIVOT_TABLETYPE_GOOGLE_AREACHART
ABM.PIVOT_TABLETYPE_GOOGLE_BARCHART
ABM.PIVOT_TABLETYPE_GOOGLE_LINECHART
ABM.PIVOT_TABLETYPE_GOOGLE_SCATTERCHART
ABM.PIVOT_TABLETYPE_GOOGLE_STACKEDBARCHART
ABM.PIVOT_TABLETYPE_HEATMAP
ABM.PIVOT_TABLETYPE_ROWHEATMAP
ABM.PIVOT_TABLETYPE_TABLE
ABM.PIVOT_TABLETYPE_TABLEBARCHART
ABM.PLANNER_MENUTYPE_DAY
ABM.PLANNER_MENUTYPE_HOUR
ABM.PLANNER_MENUTYPE_MIN
ABM.PLANNER_MENU_COPY
ABM.PLANNER_MENU_CUT
ABM.PLANNER_MENU_DELETE
ABM.PLANNER_MENU_PASTE
ABM.PLANNER_MENU_SETFREE
ABM.PLANNER_MENU_SETNOTAVAILABLE
ABM.PLANNER_STATUS_FREE_AVAILABLE
ABM.PLANNER_STATUS_FREE_NOTAVAILABLE
ABM.PLANNER_STATUS_USED_AVAILABLE
ABM.PLANNER_STATUS_USED_NOTAVAILABLE
ABM.POSITION_BOTTOMLEFT
ABM.POSITION_BOTTOMRIGHT
ABM.POSITION_TOPLEFT
ABM.POSITION_TOPRIGHT
ABM.PRINT_PAGEBREAK_AFTER_ALWAYS
ABM.PRINT_PAGEBREAK_AFTER_AUTO
ABM.PRINT_PAGEBREAK_AFTER_AVOID
ABM.PRINT_PAGEBREAK_AFTER_INHERIT
ABM.PRINT_PAGEBREAK_AFTER_INITIAL
ABM.PRINT_PAGEBREAK_AFTER_LEFT
ABM.PRINT_PAGEBREAK_AFTER_RIGHT
ABM.PRINT_PAGEBREAK_BEFORE_ALWAYS
ABM.PRINT_PAGEBREAK_BEFORE_AUTO
ABM.PRINT_PAGEBREAK_BEFORE_AVOID
ABM.PRINT_PAGEBREAK_BEFORE_INHERIT
ABM.PRINT_PAGEBREAK_BEFORE_INITIAL
ABM.PRINT_PAGEBREAK_BEFORE_LEFT
ABM.PRINT_PAGEBREAK_BEFORE_RIGHT
ABM.PRINT_PAGEBREAK_INSIDE_AUTO
ABM.PRINT_PAGEBREAK_INSIDE_AVOID
ABM.PRINT_PAGEBREAK_INSIDE_INHERIT
ABM.PRINT_PAGEBREAK_INSIDE_INITIAL
ABM.PRINT_SIZE_A3
ABM.PRINT_SIZE_A4
ABM.PRINT_SIZE_A5
ABM.PRINT_SIZE_LETTER
ABM.RANGE_CONNECT_FALSE
ABM.RANGE_CONNECT_TRUE
ABM.RANGE_DIRECTION_LEFTTORIGHT
ABM.RANGE_DIRECTION_RIGHTTOLEFT
ABM.SECTION_BUTTONTYPE_DOWN
ABM.SECTION_BUTTONTYPE_UP
ABM.SIDEBAR_AUTO
ABM.SIDEBAR_MANUAL_ALWAYSHIDE
ABM.SIDEBAR_MANUAL_HIDEMEDIUMSMALL
ABM.SITEMAP_FREQ_ALWAYS
ABM.SITEMAP_FREQ_DAILY
ABM.SITEMAP_FREQ_HOURLY
ABM.SITEMAP_FREQ_MONTHLY
ABM.SITEMAP_FREQ_NEVER
ABM.SITEMAP_FREQ_NONE
ABM.SITEMAP_FREQ_WEEKLY
ABM.SITEMAP_FREQ_YEARLY
ABM.SIZE_A
ABM.SIZE_CUSTOM
ABM.SIZE_H1
ABM.SIZE_H2
ABM.SIZE_H3
ABM.SIZE_H4
ABM.SIZE_H5
ABM.SIZE_H6
ABM.SIZE_PARAGRAPH
ABM.SIZE_SMALL
ABM.SIZE_SPAN
ABM.SLIDER_CONNECT_LOWER
ABM.SLIDER_CONNECT_NONE
ABM.SLIDER_CONNECT_UPPER
ABM.SMARTWIZARD_RESPONSIVE_OVERUNDER
ABM.SMARTWIZARD_RESPONSIVE_USEALTICON
ABM.SMARTWIZARD_STATE_ACTIVE
ABM.SMARTWIZARD_STATE_DISABLED
ABM.SMARTWIZARD_STATE_DONE
ABM.SMARTWIZARD_STATE_ERROR
ABM.SMARTWIZARD_STATE_HIDDEN
ABM.SOCIALOAUTH_FACEBOOK
ABM.SOCIALOAUTH_FOURSQUARE
ABM.SOCIALOAUTH_GOOGLEPLUS
ABM.SOCIALOAUTH_INSTAGRAM
ABM.SOCIALOAUTH_LINKEDIN
ABM.SOCIALOAUTH_SOUNDCLOUD
ABM.SOCIALOAUTH_TWITTER
ABM.SOCIALOAUTH_WINDOWSLIVE
ABM.SOCIALOAUTH_YAHOO
ABM.SOCIALSHAREBUTTONTYPE_BASIC
ABM.SOCIALSHAREBUTTONTYPE_BUTTONLABEL
ABM.SOCIALSHAREBUTTONTYPE_BUTTONLABELCOUNT
ABM.SOCIALSHAREBUTTONTYPE_ICONSCOUNT
ABM.SOCIALSHAREBUTTONTYPE_ICONSCOUNTINSIDE
ABM.SOCIALSHAREBUTTONTYPE_ICONSONLY
ABM.SOCIALSHARE_EMAIL
ABM.SOCIALSHARE_FACEBOOK
ABM.SOCIALSHARE_FACEBOOKEXTENDED
ABM.SOCIALSHARE_FACEBOOKLIKE
ABM.SOCIALSHARE_GOOGLEPLUS
ABM.SOCIALSHARE_LINKEDIN
ABM.SOCIALSHARE_PINTREST
ABM.SOCIALSHARE_TWITTER
ABM.SOCIALSHARE_WHATSAPP
ABM.SOCIALSHARTHEMETYPE_CLASSIC
ABM.SOCIALSHARTHEMETYPE_FLAT
ABM.SOCIALSHARTHEMETYPE_MINIMA
ABM.SOCIALSHARTHEMETYPE_PLAIN
ABM.SVGELEMENT_ARC
ABM.SVGELEMENT_CIRCLE
ABM.SVGELEMENT_ELLIPSE
ABM.SVGELEMENT_GROUP
ABM.SVGELEMENT_IMAGE
ABM.SVGELEMENT_LINE
ABM.SVGELEMENT_PATH
ABM.SVGELEMENT_POLYGON
ABM.SVGELEMENT_POLYLINE
ABM.SVGELEMENT_RECT
ABM.SVGELEMENT_TEXT
ABM.SVGELEMENT_TEXTARRAY
ABM.SVGELEMENT_UNDEFINED
ABM.TABLECELL_HORIZONTALALIGN_CENTER
ABM.TABLECELL_HORIZONTALALIGN_LEFT
ABM.TABLECELL_HORIZONTALALIGN_RIGHT
ABM.TABLECELL_VERTICALALIGN_BOTTOM
ABM.TABLECELL_VERTICALALIGN_MIDDLE
ABM.TABLECELL_VERTICALALIGN_TOP
ABM.TEXTALIGN_CENTER
ABM.TEXTALIGN_JUSTIFY
ABM.TEXTALIGN_LEFT
ABM.TEXTALIGN_RIGHT
ABM.TOOLTIP_BOTTOM
ABM.TOOLTIP_LEFT
ABM.TOOLTIP_RIGHT
ABM.TOOLTIP_TOP
ABM.TOTP_ENCRYPT_SHA1
ABM.TOTP_ENCRYPT_SHA256
ABM.TOTP_ENCRYPT_SHA512
ABM.TWEEN_EASE
ABM.TWEEN_EASEIN
ABM.TWEEN_EASEINCIRC
ABM.TWEEN_EASEINCUBIC
ABM.TWEEN_EASEINEXPO
ABM.TWEEN_EASEINOUT
ABM.TWEEN_EASEINOUTCIRC
ABM.TWEEN_EASEINOUTCUBIC
ABM.TWEEN_EASEINOUTEXPO
ABM.TWEEN_EASEINOUTQUAD
ABM.TWEEN_EASEINOUTQUART
ABM.TWEEN_EASEINOUTQUINT
ABM.TWEEN_EASEINOUTSINE
ABM.TWEEN_EASEINQUAD
ABM.TWEEN_EASEINQUART
ABM.TWEEN_EASEINQUINT
ABM.TWEEN_EASEINSINE
ABM.TWEEN_EASEOUT
ABM.TWEEN_EASEOUTCIRC
ABM.TWEEN_EASEOUTCUBIC
ABM.TWEEN_EASEOUTEXPO
ABM.TWEEN_EASEOUTQUAD
ABM.TWEEN_EASEOUTQUART
ABM.TWEEN_EASEOUTQUINT
ABM.TWEEN_EASEOUTSINE
ABM.TWEEN_LINEAR
ABM.TWEEN_SPRING
ABM.TWEEN_SWING
ABM.UITYPE_ABMCONTAINER
ABM.UITYPE_ACTIONBUTTON
ABM.UITYPE_AUDIOPLAYER
ABM.UITYPE_BADGE
ABM.UITYPE_BUTTON
ABM.UITYPE_CALENDAR
ABM.UITYPE_CANVAS
ABM.UITYPE_CARD
ABM.UITYPE_CHART
ABM.UITYPE_CHAT
ABM.UITYPE_CHECKBOX
ABM.UITYPE_CHIP
ABM.UITYPE_CHRONOLIST
ABM.UITYPE_CODELABEL
ABM.UITYPE_COMBO
ABM.UITYPE_COMPOSER
ABM.UITYPE_CUSTOMCARD
ABM.UITYPE_CUSTOMCOMPONENT
ABM.UITYPE_DIVIDER
ABM.UITYPE_DTPICKER
ABM.UITYPE_DTSCROLLER
ABM.UITYPE_EDITOR
ABM.UITYPE_FILEINPUT
ABM.UITYPE_FILEMANAGER
ABM.UITYPE_FLEXWALL
ABM.UITYPE_GOOGLEMAP
ABM.UITYPE_IMAGE
ABM.UITYPE_IMAGESLIDER
ABM.UITYPE_INPUTFIELD
ABM.UITYPE_ITEMLIST
ABM.UITYPE_LABEL
ABM.UITYPE_LIST
ABM.UITYPE_MHEADCOMPONENT
ABM.UITYPE_MMENUCOMPONENT
ABM.UITYPE_MODALSHEET
ABM.UITYPE_PAGINATION
ABM.UITYPE_PARALLAX
ABM.UITYPE_PATTERNLOCK
ABM.UITYPE_PDFVIEWER
ABM.UITYPE_PERCENTSLIDER
ABM.UITYPE_PIVOTTABLE
ABM.UITYPE_PLANNER
ABM.UITYPE_RADIOGROUP
ABM.UITYPE_RANGE
ABM.UITYPE_REPORTCOMPONENT
ABM.UITYPE_SIGNATUREPAD
ABM.UITYPE_SLIDER
ABM.UITYPE_SMARTWIZARD
ABM.UITYPE_SOCIALOAUTH
ABM.UITYPE_SOCIALSHARE
ABM.UITYPE_SVGSURFACE
ABM.UITYPE_SWITCH
ABM.UITYPE_TABEL
ABM.UITYPE_TABELMUTABLE
ABM.UITYPE_TABS
ABM.UITYPE_TIMELINE
ABM.UITYPE_TREETABLE
ABM.UITYPE_UNDEFINED
ABM.UITYPE_UPLOAD
ABM.UITYPE_VIDEO
ABM.VALID_FALSE
ABM.VALID_TRUE
ABM.VALID_UNDETERMINED
ABM.VIEWER_DESKTOP
ABM.VIEWER_LAPTOP
ABM.VIEWER_MOBILE
ABM.VIEWER_TABLET
ABM.VISIBILITY_ALL
ABM.VISIBILITY_HIDE_ALL
ABM.VISIBILITY_HIDE_ON_LARGE_ONLY
ABM.VISIBILITY_HIDE_ON_MEDIUM_AND_ABOVE
ABM.VISIBILITY_HIDE_ON_MEDIUM_AND_BELOW
ABM.VISIBILITY_HIDE_ON_MEDIUM_ONLY
ABM.VISIBILITY_HIDE_ON_SMALL_ONLY
ABM.VISIBILITY_SHOW_ON_LARGE_ONLY
ABM.VISIBILITY_SHOW_ON_MEDIUM_AND_ABOVE
ABM.VISIBILITY_SHOW_ON_MEDIUM_AND_BELOW
ABM.VISIBILITY_SHOW_ON_MEDIUM_ONLY
ABM.VISIBILITY_SHOW_ON_SMALL_ONLY
ABM.WAVESEFFECT_BLOCK
ABM.WAVESEFFECT_CUSTOM
ABM.WAVESEFFECT_DEFAULT
ABM.WAVESEFFECT_GREEN
ABM.WAVESEFFECT_LIGHT
ABM.WAVESEFFECT_NONE
ABM.WAVESEFFECT_ORANGE
ABM.WAVESEFFECT_PURPLE
ABM.WAVESEFFECT_RED
ABM.WAVESEFFECT_TEAL
ABM.WAVESEFFECT_YELLOW
ABM.YOUTUBESTATE_BUFFERING
ABM.YOUTUBESTATE_ENDED
ABM.YOUTUBESTATE_PAUSED
ABM.YOUTUBESTATE_PLAYING
ABM.YOUTUBESTATE_UNSTARTED
ABM.YOUTUBESTATE_VIDEOCUED
ABM.ZDEPTH_1
ABM.ZDEPTH_2
ABM.ZDEPTH_3
ABM.ZDEPTH_4
ABM.ZDEPTH_5
ABM.ZDEPTH_DEFAULT
ABM.ZDEPTH_REMOVE
 

Harris

Expert
Licensed User
Longtime User
Lesson 9 - Tips and Tricks

This section shall expose some items that are useful when developing, testing and deploying our apps.

Log Each Button Click Event

On each page, in the sub Page_ParseEvent(Params As Map) add a log item to show what the events are - and the params required.
This helps you discover "why" your assumed event section is not being raised (for example)...

B4X:
Sub Page_ParseEvent(Params As Map)
    Dim eventName As String = Params.Get("eventname")
    Dim eventParams() As String = Regex.Split(",",Params.Get("eventparams"))

' log each event click...
    Log(" Event name: "&eventName&"  "&Params)


Save a Log File To Disk

Trying to discover why your app on the remote server "sometimes" has issues can be so much fun...

Write a file with all log outputs you can look at later - when issues are reported.

In the the AppStart section of Main, add - ABMShared.RedirectOutput(File.DirApp,"mylogs.txt") - as the last line...

B4X:
Sub RedirectOutput (Dir As String, FileName As String) 'ignore
   #if RELEASE
   Dim out As OutputStream = File.OpenOutput(Dir, FileName, False) 'Set to True to append the logs
   Dim ps As JavaObject
   ps.InitializeNewInstance("java.io.PrintStream", Array(out, True, "utf8"))
   Dim jo As JavaObject
   jo.InitializeStatic("java.lang.System")
   jo.RunMethod("setOut", Array(ps))
   jo.RunMethod("setErr", Array(ps))
   #end if
End Sub

Watch For Incoming Files

My server app collects much data from mobile clients. This data consists of one or more files contained in a zipped file.
When the zips arrive (in a defined folder), they need to be un-zipped, in a select folder, so users can view the contents...

Check jFileWatcher in the libs tab...

In Main:

Sub Process_Globals
Public fw As FileWatcher
Public ecmFolder As String = File.DirApp &"/www/myapp/ecmfiles"


Sub AppStart (Args() As String)
fw.Initialize("fw").SetWatchList(Array As String(ecmFolder)).StartWatching ' watch this folder for new files...

When FileWatcher event is raised (new incoming file):

B4X:
Sub fw_CreationDetected(FileName As String)
    Log("CreationDetected: " & FileName)    'Logs the creation of a new file or folder
    If inprocess = False Then
        inprocess = True
        proctimer.Enabled = True
    End If
 
End Sub

I start a Timer to process the batch...
B4X:
' timer sub...
Sub prtim_tick
 
        Dim lof As List
        lof.Initialize
        lof = File.ListFiles(ecmFolder)   ' create a list of filenames in this folder to process
        For i  = 0 To lof.Size -1
            Dim str As String
            str = lof.Get(i)
            If str.Contains(".zip") Then
               csu.CallSubDelayedPlus2(Me,  "ProcessEcmZips",  2000,  Array(str))
            End If
        Next
        proctimer.Enabled = False   ' stop the timer and reset the flag
        inprocess = False
 
End Sub

' process sub...
Sub ProcessEcmZips(fn() As Object)
    Log(" will process this file: "&fn(0))

    ' Now process the zip file...
    ' delete the incoming file so it won't get re-processed...
End Sub

Use Page.MsgBox2 For Modal Dialogs

Way back when, we were forced to create our own modal dialogs using sheets. No longer the case - (sweet)...
Position them anywhere and style them to your hearts content!

Example:
page.Msgbox2("DOWNL","Download the Android Mobile App","Get Device Application","Download","Cancel",False,ABM.MSGBOX_TYPE_QUESTION,False,ABM.MSGBOX_POS_CENTER_CENTER,"")

Result Dialog:
mdiag.JPG


The dialog result sub... This is where we take action based on "which" dialog was shown and "what" button was clicked...
This keeps all your click actions in one nice tight sub...

B4X:
Sub page_MsgboxResult(returnName As String, result As String)
 
 If result = ABM.MSGBOX_RESULT_OK Then  ' log only when OK was clicked...
    Log(" OK was pressed   Return name: "&returnName&"  result: "&result)
 End If

  Select Case returnName
     Case "DOWNL"
           ' ...  Start of "DOWNL"
           Log(" what is result: "&result)
           Select Case result
              Case "abmok"
                Dim add As String = "../../apks/tinspect.apk"
                ws.Eval("window.location = arguments[0]", Array As Object(add))
                ws.Flush
                Log(" DOWNL - tried to download the apk")
            End Select
           ' ...  End of "DOWNL"

     Case "NEXT1"  ' some other Msgbox2 on the same page...
            ' ...
     Case "NEXT2"  ' some other Msgbox2 on the same page...
            ' ...
     Case "NEXT3"  ' some other Msgbox2 on the same page...
            ' ...
 
 End Select
 
End Sub


Using page.ShowToastWithReturns

This example ( from member David Elkington ) explains how to use Toast Messages effectively...

B4X:
'Call the toast...

If bolToastShowing = False Then ' I use this to stop the reoccurrence

    page.ShowToastWithReturns("tConfirmEmail","ToastPurpleC","Send email:",5000, Array As String("Click to Confirm"),Array As String("Yes"),False)
    bolToastShowing = True

End If


Sub Page_ToastClicked(toastID As String, Action As String)

If toastID="tConfirmEmail" Then
   If Action="Yes" Then
'  Do your email action

      page.showToast("tDone","ToastGreen","Email has been queued",2000,False)
      bolToastShowing=False
   End If

End If
End Sub

Sub Page_ToastDismissed(ToastId As String)   ' toast dismissed...
  If ToastId="tconfirmemail" Then
     bolToastShowing=False
   End If
End Sub


Use Unique ID's When Creating Elements / Objects

This is very important to ensure formatting / themes are assigned properly.
For example when creating ABMTable rows:

B4X:
public Sub ConnectPage()       
    '    connecting the navigation bar
    ABMShared.ConnectNavigationBar(page)

    Dim tb As ABMTable
    tb.Initialize(page, "tbl", False, False, True, "ttt")
    tb.SetHeaders(Array As String("Head1", "Head2", "Head3"))
    Dim alt As Boolean = True
    For i = 0 To 10
        Dim row As List
        Dim rowT As List
        row.Initialize
        rowT.Initialize
        For j = 0 To 2
            Dim st As String = Rnd(0,1000)
            row.Add(st)
            If alt Then rowT.Add("cc1") Else rowT.Add("cc2")
        Next

'******************************************************
'        tb.AddRow("", row)   ' this is wrong - no unique ID
        tb.AddRow("uid" & i, row)   ' this is correct - has unique ID for each row in table

'******************************************************


        tb.SetRowThemes(rowT)
        alt = Not(alt)
    Next
    page.Cell(1, 1).AddComponent(tb)

 
    ' refresh the page
    page.Refresh
 
    ' Tell the browser we finished loading
    page.FinishedLoading
    ' restoring the navigation bar position
    page.RestoreNavigationBarPosition

End Sub

Run Your App in Debug Mode to Generate the CopyMeWithJar.needs File

In debug mode, your code is analyzed for newly added components and this file is updated to include these components. Run in debug just before release of your app to ensure this file gets updated.


Got any tips / tricks or useful snippets for us ABMers?
PM me and I will add them to this section!
 
Last edited:
Top