You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/developer-guide/Advanced-Topics-Under-The-Hood.asciidoc
+24-24Lines changed: 24 additions & 24 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,7 +9,7 @@ These hints are often referred to as "build hints" or "build arguments", they ar
9
9
You can set these hints by right clicking the project in the IDE and selecting #Codename One# -> #Codename One Settings# -> #Build Hints#. The hints use the `key=value` style of data.
10
10
11
11
.The build hints UI in Codename One Settings
12
-
image::img/developer-guide/build-hints-codenameone-settings.png[The build hints UI in Codename One Settings,scaledwidth=50%]
12
+
image::img/build-hints-codenameone-settings.png[The build hints UI in Codename One Settings,scaledwidth=50%]
13
13
14
14
You can set the build hints in the `codenameone_settings.properties` file directly notice that when you do that all settings need to start with the `codename1.arg.` prefix. When editing the properties file directly we would need to define something like `android.debug=true` as `codename1.arg.android.debug=true`.
15
15
@@ -545,30 +545,30 @@ f.show();
545
545
If you explicitly lower the target SDK (e.g. `android.targetSDKVersion=21`) and install this app on an Android 6 device you will still see the legacy install prompt with all permissions listed up front:
546
546
547
547
.Install UI when using the old permissions system
548
-
image::img/developer-guide/marshmallow-permissions-level21.png[Install UI when using the old permissions system,scaledwidth=20%]
548
+
image::img/marshmallow-permissions-level21.png[Install UI when using the old permissions system,scaledwidth=20%]
549
549
550
550
When you keep the default target (API 33+) the installer defers to the runtime permission flow and the install UI looks like this instead:
551
551
552
552
.Install UI when using the new permissions system
553
-
image::img/developer-guide/marshmallow-permissions-level23.png[Install UI when using the new permissions system,scaledwidth=20%]
553
+
image::img/marshmallow-permissions-level23.png[Install UI when using the new permissions system,scaledwidth=20%]
554
554
555
555
When we launch the UI under the old permissions system we see the contacts instantly. In the new system we are presented with this UI:
556
556
557
557
.Native permission prompt first time
558
-
image::img/developer-guide/marshmallow-permissions-first-request.png[Native permission prompt first time,scaledwidth=20%]
558
+
image::img/marshmallow-permissions-first-request.png[Native permission prompt first time,scaledwidth=20%]
559
559
560
560
If we accept and allow all is good and the app loads as usual but if we deny then Codename One gives the user another chance to request the permission. Notice that in this case you can customize the prompt string as explained below.
561
561
562
562
.Codename One permission prompt
563
-
image::img/developer-guide/marshmallow-permissions-codenameone-prompt.png[Codename One permission prompt,scaledwidth=20%]
563
+
image::img/marshmallow-permissions-codenameone-prompt.png[Codename One permission prompt,scaledwidth=20%]
564
564
565
565
If we select don't ask then you will get a blank screen since the contacts will return as a 0 length array. This makes
566
566
sense as the user is aware he denied permission and the app will still function as expected on a device where
567
567
no contacts are available. However, if the user realizes his mistake he can double back and ask to re-prompt for
568
568
permission in which case he will see this native prompt:
569
569
570
570
.Native permission prompt second time
571
-
image::img/developer-guide/marshmallow-permissions-second-request.png[Native permission prompt second time,scaledwidth=20%]
571
+
image::img/marshmallow-permissions-second-request.png[Native permission prompt second time,scaledwidth=20%]
572
572
573
573
Notice that denying this second request will not trigger another Codename One prompt.
574
574
@@ -600,7 +600,7 @@ The following permission keys are supported: "android.permission.READ_PHONE_STAT
600
600
You can simulate permission prompts by checking that option in the simulator menu.
601
601
602
602
.Simulate permission prompts menu item in the simulator
603
-
image::img/developer-guide/simulate-permission-prompts.png[Simulate permission prompts menu item in the simulator,scaledwidth=10%]
603
+
image::img/simulate-permission-prompts.png[Simulate permission prompts menu item in the simulator,scaledwidth=10%]
604
604
605
605
This will produce a dialog to the user whenever this happens in Android and will try to act in a similar way to the device. Notice that you can test it in the iOS simulator too.
606
606
@@ -640,7 +640,7 @@ With Android Studio this is sometimes as very easy task as it is possible to act
640
640
By default you should be able to open the gradle project in Android Studio and just run it. To get this to work open the Android Studio #Setting# and select gradle *2.11*.
641
641
642
642
.Gradle settings UI in Android Studio (notice you need gradle 2.11 and not 2.8 as pictured here)
643
-
image::img/developer-guide/gradle-settings.png[Gradle settings UI in Android Studio,scaledwidth=50%]
643
+
image::img/gradle-settings.png[Gradle settings UI in Android Studio,scaledwidth=50%]
644
644
645
645
If this works for you then you can ignore the section below.
646
646
@@ -702,22 +702,22 @@ public interface MyNative extends NativeInterface {
702
702
We now need to right click the class in the IDE and select the #Generate Native Access# menu item:
703
703
704
704
.Generating the native code
705
-
image::img/developer-guide/native-interfaces-generate-menu.png[Generating the native code,scaledwidth=20%]
705
+
image::img/native-interfaces-generate-menu.png[Generating the native code,scaledwidth=20%]
706
706
707
707
.Once generated we are prompted that the native code is in the "native" directory
708
-
image::img/developer-guide/native-interfaces-generated.png[Once generated we are prompted that the native code is in the "native" directory,scaledwidth=40%]
708
+
image::img/native-interfaces-generated.png[Once generated we are prompted that the native code is in the "native" directory,scaledwidth=40%]
709
709
710
710
We can now look int the #native# directory in the project root (in NetBeans you can see that in the #Files# tab) and you can see something that looks like this:
711
711
712
712
.Native directory structure containing stubs for the various platforms
713
-
image::img/developer-guide/native-interfaces-native-hierarchy.png[Native directory structure containing stubs for the various platforms,scaledwidth=30%]
713
+
image::img/native-interfaces-native-hierarchy.png[Native directory structure containing stubs for the various platforms,scaledwidth=30%]
714
714
715
715
These are effectively stubs you can edit to implement the methods in native code.
716
716
717
717
TIP: If you re-run the #Generate Native Access# tool you will get this dialog, if you answer yes all the files will be overwritten, if you answer no only files you deleted/renamed will be recreated
718
718
719
719
.Running "Generate Native Access" when some/all of the native files exist already
720
-
image::img/developer-guide/native-interfaces-generated-existing.png[Running "Generate Native Access" when some/all of the native files exist already,scaledwidth=40%]
720
+
image::img/native-interfaces-generated-existing.png[Running "Generate Native Access" when some/all of the native files exist already,scaledwidth=40%]
721
721
722
722
For now lets leave the stubs and come back to them soon. From the Codename One Java code we can call the implementation of this native interface using:
723
723
@@ -1686,7 +1686,7 @@ Support for JAR files in Codename One has been a source of confusion so its prob
1686
1686
The first source of confusion is changing the classpath. You should NEVER change the classpath or add an external JAR via the IDE classpath UI. The reasoning here is very simple, these IDE's don't package the JAR's into the final executable and even if they did these JAR's would probably use features unavailable or inappropriate for the device (e.g. `java.io.File` etc.).
1687
1687
1688
1688
.Don't change the classpath, this is how it should look for a typical Java 8 Codename One application
1689
-
image::img/developer-guide/cn1libs-dont-change-classpath.png[Don't change the classpath, this is how it should look for a typical Java 8 Codename One application,scaledwidth=40%]
1689
+
image::img/cn1libs-dont-change-classpath.png[Don't change the classpath, this is how it should look for a typical Java 8 Codename One application,scaledwidth=40%]
1690
1690
1691
1691
Cn1libs are Codename One's file format for 3rd party extensions. It's physicially a zip file containing other zip files and some meta-data.
1692
1692
@@ -1711,7 +1711,7 @@ Cn1lib’s address the modularity aspect allowing you to break that down. Existi
1711
1711
Codename One has a large repository of https://www.codenameone.com/cn1libs.html[3rd party cn1libs], you can install a cn1lib by placing it in the lib directory of your project then right clicking the project and selecting #Codename One# -> #Refresh cn1lib files#.
1712
1712
1713
1713
.Refresh cn1lib files menu option
1714
-
image::img/developer-guide/cn1libs-refresh.png[Refresh cn1lib files menu option,scaledwidth=40%]
1714
+
image::img/cn1libs-refresh.png[Refresh cn1lib files menu option,scaledwidth=40%]
1715
1715
1716
1716
Once refreshed the content of the cn1lib will be available to code completion and you could just use it.
1717
1717
@@ -1731,10 +1731,10 @@ The native files are extracted to `lib/impl/native`. The classpath for the main
1731
1731
Creating a cn1lib is trivial, we will get into more elaborate uses soon enough but for a hello world cn1lib we can just use this 2 step process:
1732
1732
1733
1733
.Select the CodenameOne Library Option
1734
-
image::img/developer-guide/cn1lib-create-step1.png[Select the CodenameOne Library Option,scaledwidth=30%]
1734
+
image::img/cn1lib-create-step1.png[Select the CodenameOne Library Option,scaledwidth=30%]
1735
1735
1736
1736
.Select the file name/destination. Notice that a Java 8 cn1lib requires Java 8 support in the parent project!
1737
-
image::img/developer-guide/cn1lib-create-step2.png[Select the file name/destination. Notice that a Java 8 cn1lib requires Java 8 support in the parent project!,scaledwidth=30%]
1737
+
image::img/cn1lib-create-step2.png[Select the file name/destination. Notice that a Java 8 cn1lib requires Java 8 support in the parent project!,scaledwidth=30%]
1738
1738
1739
1739
Once we go thru these steps we can define any source file within the library and it will be accessible to the users of the library.
1740
1740
@@ -1964,7 +1964,7 @@ hi.show();
1964
1964
----
1965
1965
1966
1966
.Drag and drop demo
1967
-
image::img/developer-guide/draganddrop-rearrange-game.png[Drag and drop demo,scaledwidth=20%]
1967
+
image::img/draganddrop-rearrange-game.png[Drag and drop demo,scaledwidth=20%]
1968
1968
1969
1969
1970
1970
To enable dragging a component it must be flagged as draggable using `setDraggable(true)`, to allow dropping the component onto another component you must first enable the drop target with `setDropTarget(true)` and override some methods (more on that later).
@@ -2178,13 +2178,13 @@ The following diagram shows the dependencies in a native library:
2178
2178
2179
2179
[[fc8a77d2-61e0-11e5-9ecf-bf381d4ac966]]
2180
2180
.Relationship between native & Codename One API UML Diagram
2181
-
image::img/developer-guide/fc8a77d2-61e0-11e5-9ecf-bf381d4ac966.png[Relationship between native and Codename One API UML Diagram,scaledwidth=50%]
2181
+
image::img/fc8a77d2-61e0-11e5-9ecf-bf381d4ac966.png[Relationship between native and Codename One API UML Diagram,scaledwidth=50%]
2182
2182
2183
2183
In the specific case of our FreshDesk API, the public API and classes will look like:
2184
2184
2185
2185
[[a5fe88406-61e4-11e5-951e-e09bd28a93c9]]
2186
2186
.Freshdesk API Integration
2187
-
image::img/developer-guide/5fe88406-61e4-11e5-951e-e09bd28a93c9.png[Freshdesk API Integration,scaledwidth=30%]
2187
+
image::img/5fe88406-61e4-11e5-951e-e09bd28a93c9.png[Freshdesk API Integration,scaledwidth=30%]
2188
2188
2189
2189
===== Things to Notice
2190
2190
@@ -2692,13 +2692,13 @@ Now that we have set up our public API and our native interface, it is time to w
2692
2692
2693
2693
[[c9d4b9cc-61f6-11e5-8b67-4691600188cd]]
2694
2694
.Generate Native Access Menu Item
2695
-
image::img/developer-guide/c9d4b9cc-61f6-11e5-8b67-4691600188cd.png[Generate Native Access Menu Item,scaledwidth=20%]
2695
+
image::img/c9d4b9cc-61f6-11e5-8b67-4691600188cd.png[Generate Native Access Menu Item,scaledwidth=20%]
2696
2696
2697
2697
This will generate a separate directory for each platform inside your project's `native` directory:
I.e. we just list the framework names separated by semicolons. Notice that my list in the above image doesn't include all of the frameworks that they list because many of the frameworks are already included by default (I obtained the default list by simply building the project with "include sources" checked, then looked at the frameworks that were included).
3086
3086
@@ -3168,7 +3168,7 @@ hi.show();
3168
3168
----
3169
3169
3170
3170
.Center layout staircase effect with margin
3171
-
image::img/developer-guide/center-layout.png[Center layout staircase effect with margin,scaledwidth=20%]
3171
+
image::img/center-layout.png[Center layout staircase effect with margin,scaledwidth=20%]
.The slide transition moves both incoming and outgoing forms together
459
-
image::img/developer-guide/transition-slide.jpg[The slide transition moves both incoming and outgoing forms together,scaledwidth=70%]
459
+
image::img/transition-slide.jpg[The slide transition moves both incoming and outgoing forms together,scaledwidth=70%]
460
460
461
461
.The slide transition can be applied vertically as well
462
-
image::img/developer-guide/transition-slide-vertical.jpg[The slide transition can be applied vertically as well,scaledwidth=70%]
462
+
image::img/transition-slide-vertical.jpg[The slide transition can be applied vertically as well,scaledwidth=70%]
463
463
464
464
.Slide fade fades in the destination title while sliding the content pane it is the default on iOS
465
-
image::img/developer-guide/transition-slide-fade.jpg[Slide fade fades in the destination title while sliding the content pane its the default on iOS,scaledwidth=70%]
465
+
image::img/transition-slide-fade.jpg[Slide fade fades in the destination title while sliding the content pane its the default on iOS,scaledwidth=70%]
466
466
467
467
TIP: `SlideFade` is problematic without a title area. If you have a `Form` that lacks a title area we would recommend to disable `SlideFade` at least for that `Form`.
468
468
469
469
.With cover transitions the source form stays in place as it is covered by the destination. This transition can be played both horizontally and vertically
470
-
image::img/developer-guide/transition-cover.jpg[With cover transitions the source form stays in place as it is covered by the destination. This transition can be played both horizontally and vertically,scaledwidth=70%]
470
+
image::img/transition-cover.jpg[With cover transitions the source form stays in place as it is covered by the destination. This transition can be played both horizontally and vertically,scaledwidth=70%]
471
471
472
472
473
473
.Uncover is the inverse of cover. The destination form stays in place while the departing form moves away
474
-
image::img/developer-guide/transition-uncover.jpg[Uncover is the inverse of cover. The destination form stays in place while the departing form moves away,scaledwidth=70%]
474
+
image::img/transition-uncover.jpg[Uncover is the inverse of cover. The destination form stays in place while the departing form moves away,scaledwidth=70%]
475
475
476
476
==== Fade and Flip Transitions
477
477
478
478
The fade transition is pretty trivial and only accepts a time value since it has no directional context.
479
479
480
480
.Fade transition is probably the simplest one around
481
-
image::img/developer-guide/transition-fade.jpg[Fade transition is probably the simplest one around,scaledwidth=70%]
481
+
image::img/transition-fade.jpg[Fade transition is probably the simplest one around,scaledwidth=70%]
482
482
483
483
The https://www.codenameone.com/javadoc/com/codename1/ui/animations/FlipTransition.html[FlipTransition] is also pretty simple but unlike the others it isn't a part of the `CommonTransitions`. It has its own `FlipTransition` class.
484
484
485
485
IMPORTANT: This transition looks very different on devices as it uses native perspective transforms available only there
486
486
487
487
.Fade transition is probably the simplest one around
488
-
image::img/developer-guide/transition-flip.jpg[Fade transition is probably the simplest one around,scaledwidth=70%]
488
+
image::img/transition-flip.jpg[Fade transition is probably the simplest one around,scaledwidth=70%]
489
489
490
490
==== Bubble Transition
491
491
@@ -546,7 +546,7 @@ hi.show();
546
546
----
547
547
548
548
.Bubble transition converting a circular button to a Dialog
549
-
image::img/developer-guide/transition-bubble.png[Bubble transition converting a circular button to a Dialog,scaledwidth=12%]
549
+
image::img/transition-bubble.png[Bubble transition converting a circular button to a Dialog,scaledwidth=12%]
To support this behavior we have the https://www.codenameone.com/javadoc/com/codename1/ui/animations/MorphTransition.html[MorphTransition] class that provides this same effect coupled with a fade to
567
567
the rest of the UI (see <<mighty-morphing-components-1>>).
The animation in the splash screen and most of the following animations are achieved using the simple tool of layout animations. In Codename One components are automatically arranged into position using layout managers, however this isn’t implicit unless the device is rotated. A layout animation relies on this fact, it allows you to place components in a position (whether by using a layout manager or by using `setX`/`setY`) then invoke the layout animation code so they will slide into their “proper” position based on the layout manager rules.
56
56
@@ -66,7 +66,7 @@ Initially when entering the game form we have another animation where all the ca
This animation is really easy to accomplish although it does have several stages. In the first stage we layout the cards within a grid layout (13x4), then when the animation starts (see the https://www.codenameone.com/javadoc/com/codename1/ui/util/UITimer.html[UITimer] code within `showGameUI()`) we just change the layout to a layered layout, add the back card (so it will come out on top based on z-ordering) and invoke animate layout.
0 commit comments